diff --git a/.github/actions/analyze_compile_time_tracing/action.yml b/.github/actions/analyze_compile_time_tracing/action.yml index 1a756e69d47..4403866afbd 100644 --- a/.github/actions/analyze_compile_time_tracing/action.yml +++ b/.github/actions/analyze_compile_time_tracing/action.yml @@ -18,7 +18,7 @@ runs: using: composite steps: # Analyze compile time with ClangBuildAnalyzer - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: repository: aras-p/ClangBuildAnalyzer ref: bae0cb488cce944bfc3da9850a69ad621701ebef # version 1.6.0 @@ -40,7 +40,7 @@ runs: SUMMARY_FILE: ${{ inputs.report-summary-file }} # Aggregate individual tracing files with ninjatracing - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: repository: nico/ninjatracing ref: a669e3644cf22b29cbece31dbed2cfbf34e5f48e # no releases for this repo, this is a stable commit diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index ec488b1c6b4..7f7fff2c308 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -24,7 +24,7 @@ jobs: outputs: test-chunks: ${{ steps.set-matrix.outputs.chunk-array }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/build_4C @@ -62,7 +62,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - name: Setup developer environment for testing @@ -93,7 +93,7 @@ jobs: runs-on: ubuntu-latest if: github.ref != 'refs/heads/main' && (success() || failure()) steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: sparse-checkout: .github - uses: ./.github/actions/merge_junit_report_artifacts @@ -117,7 +117,7 @@ jobs: # Due to a bug in runner action the variables $GITHUB_WORKSPACE and ${{ github.workspace }} are different inside a container. https://github.com/actions/runner/issues/2058 # The repo gets cloned to `/__w/4C/4C` ($GITHUB_WORKSPACE) while ${{ github.workspace }} points to `/home/runner/work/4C/4C`.` # Use $GITHUB_WORKSPACE instead of ${{ github.workspace }} - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/build_4C @@ -170,7 +170,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - name: Setup developer environment for testing @@ -198,7 +198,7 @@ jobs: env: CCACHE_DIR: ${{ github.workspace }}/.ccache steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - name: Setup developer environment for testing @@ -233,7 +233,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: actions/download-artifact@v8 with: name: clang18_build-schema @@ -262,7 +262,7 @@ jobs: outputs: test-chunks: ${{ steps.set-matrix.outputs.chunk-array }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/build_4C @@ -300,7 +300,7 @@ jobs: matrix: test-chunk: ${{fromJson(needs.gcc13_no_optional_dependencies_build.outputs.test-chunks)}} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - name: Setup developer environment for testing @@ -331,7 +331,7 @@ jobs: runs-on: ubuntu-latest if: github.ref != 'refs/heads/main' && (success() || failure()) steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: sparse-checkout: .github - uses: ./.github/actions/merge_junit_report_artifacts diff --git a/.github/workflows/checkcode.yml b/.github/workflows/checkcode.yml index b9b5ff13203..1b1cd131e7e 100644 --- a/.github/workflows/checkcode.yml +++ b/.github/workflows/checkcode.yml @@ -20,7 +20,7 @@ jobs: env: SKIP: no-commit-to-branch steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Run pre-commit run: | ./utilities/set_up_dev_env.sh @@ -37,7 +37,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/configure_4C @@ -63,7 +63,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/build_4C diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 2df89c584a1..a253ca2e423 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -18,7 +18,7 @@ jobs: outputs: test-chunks: ${{ steps.set-matrix.outputs.chunk-array }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/build_4C @@ -62,7 +62,7 @@ jobs: apt-get update apt-get upgrade -y apt-get install -y llvm - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/download_directory @@ -102,7 +102,7 @@ jobs: needs: clang18_coverage_test runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: sparse-checkout: .github - uses: ./.github/actions/merge_junit_report_artifacts @@ -117,7 +117,7 @@ jobs: image: ghcr.io/4c-multiphysics/4c-dependencies-ubuntu24.04:35e0657d options: --user root --env OMPI_ALLOW_RUN_AS_ROOT=1 --env OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - name: Setup developer environment for testing diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 08fd30c8ebb..5b387f540cf 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -28,7 +28,7 @@ jobs: dependencies_hash: ${{ steps.check-docker-build-required.outputs.dependencies_hash }} build_docker_image: ${{ steps.check-docker-build-required.outputs.build_docker_image }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - id: check-docker-build-required uses: ./.github/actions/check_docker_build_required with: @@ -50,7 +50,7 @@ jobs: == 'true' }} steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Build and push image uses: ./.github/actions/build_dependencies with: @@ -76,7 +76,7 @@ jobs: == 'true' }} steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Build and push image uses: ./.github/actions/build_dependencies with: @@ -96,7 +96,7 @@ jobs: contents: read packages: write steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - id: compute-dependencies-hash uses: ./.github/actions/compute-and-check-dependencies-hash with: diff --git a/.github/workflows/docker_prebuilt_4c.yml b/.github/workflows/docker_prebuilt_4c.yml index 219bdf7ba39..284251fc555 100644 --- a/.github/workflows/docker_prebuilt_4c.yml +++ b/.github/workflows/docker_prebuilt_4c.yml @@ -23,7 +23,7 @@ jobs: id-token: write steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Log in to the Container registry uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: @@ -65,7 +65,7 @@ jobs: id-token: write steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Log in to the Container registry uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index ca1abdd61a3..e3ea9cd8c03 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -26,7 +26,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/build_4C @@ -52,7 +52,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/build_4C diff --git a/.github/workflows/nightly_tests.yml b/.github/workflows/nightly_tests.yml index 05120243630..f6f5864e674 100644 --- a/.github/workflows/nightly_tests.yml +++ b/.github/workflows/nightly_tests.yml @@ -18,7 +18,7 @@ jobs: outputs: test-chunks: ${{ steps.set-matrix.outputs.chunk-array }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/build_4C @@ -55,7 +55,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - name: Setup developer environment for testing @@ -86,7 +86,7 @@ jobs: runs-on: ubuntu-latest if: success() || failure() steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: sparse-checkout: .github - uses: ./.github/actions/merge_junit_report_artifacts @@ -105,7 +105,7 @@ jobs: outputs: test-chunks: ${{ steps.set-matrix.outputs.chunk-array }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/build_4C @@ -212,7 +212,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - name: Setup developer environment for testing @@ -243,7 +243,7 @@ jobs: runs-on: ubuntu-latest if: success() || failure() steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: sparse-checkout: .github - uses: ./.github/actions/merge_junit_report_artifacts @@ -262,7 +262,7 @@ jobs: outputs: test-chunks: ${{ steps.set-matrix.outputs.chunk-array }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/build_4C @@ -299,7 +299,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - name: Setup developer environment for testing @@ -336,7 +336,7 @@ jobs: outputs: test-chunks: ${{ steps.set-matrix.outputs.chunk-array }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/build_4C @@ -373,7 +373,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - name: Setup developer environment for testing @@ -404,7 +404,7 @@ jobs: runs-on: ubuntu-latest if: success() || failure() steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: sparse-checkout: .github - uses: ./.github/actions/merge_junit_report_artifacts @@ -423,7 +423,7 @@ jobs: outputs: test-chunks: ${{ steps.set-matrix.outputs.chunk-array }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/build_4C @@ -460,7 +460,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - name: Setup developer environment for testing @@ -491,7 +491,7 @@ jobs: runs-on: ubuntu-latest if: success() || failure() steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: sparse-checkout: .github - uses: ./.github/actions/merge_junit_report_artifacts @@ -510,7 +510,7 @@ jobs: env: CCACHE_DIR: ${{ github.workspace }}/.ccache steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Check docker hash uses: ./.github/actions/compute-and-check-dependencies-hash - uses: ./.github/actions/build_4C @@ -543,7 +543,7 @@ jobs: run: | apt-get update apt-get install -y git-lfs - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: # for performance tests, we need to checkout the large meshes lfs: true diff --git a/.github/workflows/performance_report.yml b/.github/workflows/performance_report.yml index 730570e65a5..edb64dceec3 100644 --- a/.github/workflows/performance_report.yml +++ b/.github/workflows/performance_report.yml @@ -15,7 +15,7 @@ jobs: if: ${{ github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Setup python environment run: | python -m venv $GITHUB_WORKSPACE/venv diff --git a/.github/workflows/trilinos-develop.yml b/.github/workflows/trilinos-develop.yml index 6360fcbbe11..ba4193b9d5a 100644 --- a/.github/workflows/trilinos-develop.yml +++ b/.github/workflows/trilinos-develop.yml @@ -23,7 +23,7 @@ jobs: id-token: write steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Log in to the Container registry uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: @@ -61,7 +61,7 @@ jobs: outputs: test-chunks: ${{ steps.set-matrix.outputs.chunk-array }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - uses: ./.github/actions/build_4C with: cmake-preset: docker_assertions @@ -95,7 +95,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Setup developer environment for testing run: | cd $GITHUB_WORKSPACE diff --git a/apps/global_full/4C_global_full_main.cpp b/apps/global_full/4C_global_full_main.cpp index 71cec455fd1..d7fd446e0a6 100644 --- a/apps/global_full/4C_global_full_main.cpp +++ b/apps/global_full/4C_global_full_main.cpp @@ -181,8 +181,10 @@ int main(int argc, char* argv[]) } catch (Core::Exception& err) { - char line[] = "=========================================================================\n"; - std::cout << "\n\n" << line << err.what_with_stacktrace() << "\n" << line << "\n" << '\n'; + constexpr std::string_view line = + "\n=========================================================================\n"; + + std::cerr << "\n" << line << err.what_with_stacktrace() << line << "\n\n" << std::flush; if (communicators.num_groups() > 1) { diff --git a/presets/imcs/cluster/CMakePresets.json b/presets/imcs/cluster/CMakePresets.json index 7827ed9fa87..85e205699bd 100644 --- a/presets/imcs/cluster/CMakePresets.json +++ b/presets/imcs/cluster/CMakePresets.json @@ -11,7 +11,8 @@ "FOUR_C_ENABLE_NATIVE_OPTIMIZATIONS": "ON", "FOUR_C_WITH_ARBORX": "ON", "FOUR_C_WITH_FFTW": "ON", - "FOUR_C_WITH_GOOGLETEST": "OFF" + "FOUR_C_WITH_GOOGLETEST": "OFF", + "FOUR_C_WITH_VTK": "ON" } }, { @@ -52,4 +53,4 @@ } } ] -} \ No newline at end of file +} diff --git a/presets/lnm/cluster/CMakePresets.json b/presets/lnm/cluster/CMakePresets.json index b187ae3f450..5dd7bfdd79c 100644 --- a/presets/lnm/cluster/CMakePresets.json +++ b/presets/lnm/cluster/CMakePresets.json @@ -26,8 +26,8 @@ ], "cacheVariables": { "FOUR_C_TRILINOS_ROOT": "/lnm/packages/trilinos/2025-6/release", + "FOUR_C_WITH_PYTHON": "OFF", "FOUR_C_BOOST_ROOT": "/cluster/lib/gcc/9.1.0/boost_1_86_0", - "FOUR_C_PYTHON_ROOT": "/lnm/miniconda3/envs/python_3_12_env/bin", "FOUR_C_VTK_ROOT": "/lnm/packages/vtk/9-5-2/release" } }, diff --git a/src/beaminteraction/src/potential/4C_beaminteraction_potential_input.cpp b/src/beaminteraction/src/potential/4C_beaminteraction_potential_input.cpp index bf2d3baf5fd..65fb2e92eae 100644 --- a/src/beaminteraction/src/potential/4C_beaminteraction_potential_input.cpp +++ b/src/beaminteraction/src/potential/4C_beaminteraction_potential_input.cpp @@ -85,6 +85,13 @@ Core::IO::InputSpec BeamInteraction::Potential::valid_parameters() .validator = null_or(positive()), .store = in_struct(&BeamPotentialParameters::potential_reduction_length)}), + parameter("potential_reduction_function", + {.description = + "Function which describes the reduction of the potential at target beam end " + "points (only applicable in combination with potential reduction strategy).", + .default_value = ReductionFunction::cosine, + .store = in_struct(&BeamPotentialParameters::potential_reduction_function)}), + group("regularization", { parameter("type", diff --git a/src/beaminteraction/src/potential/4C_beaminteraction_potential_input.hpp b/src/beaminteraction/src/potential/4C_beaminteraction_potential_input.hpp index e76630146f5..7307113941d 100644 --- a/src/beaminteraction/src/potential/4C_beaminteraction_potential_input.hpp +++ b/src/beaminteraction/src/potential/4C_beaminteraction_potential_input.hpp @@ -77,6 +77,14 @@ namespace BeamInteraction::Potential bool write_uids{}; }; + /// function for potential reduction factor + enum class ReductionFunction + { + cosine, + polynomial_5, + polynomial_7 + }; + /// Beam potential parameters struct BeamPotentialParameters { @@ -92,6 +100,7 @@ namespace BeamInteraction::Potential bool automatic_differentiation = false; SourceTargetChoice choice_source_target{}; std::optional potential_reduction_length{}; + ReductionFunction potential_reduction_function{}; BeamPotentialVisualizationParameters runtime_output_params{}; // data container for prior element lengths for potential reduction strategy diff --git a/src/beaminteraction/src/potential/4C_beaminteraction_potential_pair_beam_to_beam.cpp b/src/beaminteraction/src/potential/4C_beaminteraction_potential_pair_beam_to_beam.cpp index d07ec1bc2dd..eeaad779f82 100644 --- a/src/beaminteraction/src/potential/4C_beaminteraction_potential_pair_beam_to_beam.cpp +++ b/src/beaminteraction/src/potential/4C_beaminteraction_potential_pair_beam_to_beam.cpp @@ -13,6 +13,7 @@ #include "4C_beaminteraction_potential_input.hpp" #include "4C_fem_general_largerotations.hpp" #include "4C_fem_general_utils_integration.hpp" +#include "4C_fem_general_utils_polynomial.hpp" #include "4C_global_data.hpp" #include "4C_io_input_parameter_container.hpp" #include "4C_linalg_fixedsizematrix.hpp" @@ -3410,27 +3411,63 @@ bool BeamInteraction::BeamToBeamPotentialPairpotential_reduction_function == + BeamInteraction::Potential::ReductionFunction::cosine) + { + potential_reduction_factor_GP = 0.5 - 0.5 * std::cos(std::numbers::pi * length_to_edge / + potential_reduction_length.value()); + pot_red_fac_deriv_l_edge = + 0.5 * std::numbers::pi / potential_reduction_length.value() * + std::sin(std::numbers::pi * length_to_edge / potential_reduction_length.value()); + pot_red_fac_2ndderiv_l_edge = + 0.5 * std::numbers::pi * std::numbers::pi / + (potential_reduction_length.value() * potential_reduction_length.value()) * + std::cos(std::numbers::pi * length_to_edge / potential_reduction_length.value()); + } + else if (params()->potential_reduction_function == + BeamInteraction::Potential::ReductionFunction::polynomial_5) + { + Core::FE::Polynomial polynomial = + Core::FE::Polynomial({0, 0, 0, 10 / std::pow(potential_reduction_length.value(), 3), + -15 / std::pow(potential_reduction_length.value(), 4), + 6 / std::pow(potential_reduction_length.value(), 5)}); + + potential_reduction_factor_GP = + polynomial.evaluate(Core::FADUtils::cast_to_double(length_to_edge)); + + pot_red_fac_deriv_l_edge = + polynomial.evaluate_derivative(Core::FADUtils::cast_to_double(length_to_edge), 1); + + pot_red_fac_2ndderiv_l_edge = + polynomial.evaluate_derivative(Core::FADUtils::cast_to_double(length_to_edge), 2); + } + else if (params()->potential_reduction_function == + BeamInteraction::Potential::ReductionFunction::polynomial_7) + { + Core::FE::Polynomial polynomial = + Core::FE::Polynomial({0, 0, 0, 0, 35 / std::pow(potential_reduction_length.value(), 4), + -84 / std::pow(potential_reduction_length.value(), 5), + 70 / std::pow(potential_reduction_length.value(), 6), + -20 / std::pow(potential_reduction_length.value(), 7)}); + + potential_reduction_factor_GP = + polynomial.evaluate(Core::FADUtils::cast_to_double(length_to_edge)); + pot_red_fac_deriv_l_edge = + polynomial.evaluate_derivative(Core::FADUtils::cast_to_double(length_to_edge), 1); + + pot_red_fac_2ndderiv_l_edge = + polynomial.evaluate_derivative(Core::FADUtils::cast_to_double(length_to_edge), 2); + } } l_edge_deriv_xi_target = 0.5 * ele2length_; diff --git a/src/core/fem/src/condition/4C_fem_condition_definition.cpp b/src/core/fem/src/condition/4C_fem_condition_definition.cpp index 1f4accdae78..4987aeb7f48 100644 --- a/src/core/fem/src/condition/4C_fem_condition_definition.cpp +++ b/src/core/fem/src/condition/4C_fem_condition_definition.cpp @@ -19,13 +19,12 @@ FOUR_C_NAMESPACE_OPEN -/* -----------------------------------------------------------------------------------------------* - | Class ConditionDefinition | - * -----------------------------------------------------------------------------------------------*/ - +/*----------------------------------------------------------------------* + *----------------------------------------------------------------------*/ Core::Conditions::ConditionDefinition::ConditionDefinition(std::string sectionname, - std::string conditionname, std::string description, Core::Conditions::ConditionType condtype, - bool buildgeometry, Core::Conditions::GeometryType gtype) + std::string conditionname, std::string description, + const Core::Conditions::ConditionType condtype, const bool buildgeometry, + const Core::Conditions::GeometryType gtype) : sectionname_(std::move(sectionname)), conditionname_(std::move(conditionname)), description_(std::move(description)), @@ -67,7 +66,7 @@ void Core::Conditions::ConditionDefinition::add_component(const Core::IO::InputS /*----------------------------------------------------------------------* *----------------------------------------------------------------------*/ void Core::Conditions::ConditionDefinition::read( - Core::IO::InputFile& input, std::vector& condition_specs) const + const Core::IO::InputFile& input, std::vector& condition_specs) const { Core::IO::InputParameterContainer container; try diff --git a/src/core/fem/src/condition/4C_fem_condition_definition.hpp b/src/core/fem/src/condition/4C_fem_condition_definition.hpp index c8cb73df50e..9181b78d17d 100644 --- a/src/core/fem/src/condition/4C_fem_condition_definition.hpp +++ b/src/core/fem/src/condition/4C_fem_condition_definition.hpp @@ -116,16 +116,16 @@ namespace Core::Conditions \param condition_specs vector of the validated condition specifications in the input to be filled. */ - void read(Core::IO::InputFile& input, std::vector& condition_specs) const; + void read(const Core::IO::InputFile& input, std::vector& condition_specs) const; /// name of my section in input file - std::string section_name() const { return sectionname_; } + [[nodiscard]] std::string section_name() const { return sectionname_; } /// my condition name - std::string name() const { return conditionname_; } + [[nodiscard]] std::string name() const { return conditionname_; } /// my GeometryType - Core::Conditions::GeometryType geometry_type() const { return gtype_; } + [[nodiscard]] Core::Conditions::GeometryType geometry_type() const { return gtype_; } /// Get the InputSpec for this ConditionDefinition [[nodiscard]] Core::IO::InputSpec spec() const; diff --git a/src/core/io/src/4C_io_exodus.cpp b/src/core/io/src/4C_io_exodus.cpp index d39f3d55666..cffd7843255 100644 --- a/src/core/io/src/4C_io_exodus.cpp +++ b/src/core/io/src/4C_io_exodus.cpp @@ -191,6 +191,12 @@ Core::IO::MeshInput::RawMesh<3> Core::IO::Exodus::read_exodus_file( // prefer std::string to store element type std::string ele_type(mychar); + if (ele_type.size() == 32) + { + std::cout << "WARNING: Your element block name " << ele_type + << " might be too long. Exodus only allows 32 characters for names.\n"; + } + // get ElementBlock name CHECK_EXODUS_CALL(ex_get_name(exo_handle, EX_ELEM_BLOCK, ebids[i], mychar)); @@ -242,6 +248,12 @@ Core::IO::MeshInput::RawMesh<3> Core::IO::Exodus::read_exodus_file( // prefer std::string to store name std::string nodesetname(mychar); + if (nodesetname.size() == 32) + { + std::cout << "WARNING: Your nodeset name " << nodesetname + << " might be too long. Exodus only allows 32 characters for names.\n"; + } + // get nodes in node set std::vector node_set_node_list(num_nodes_in_set); CHECK_EXODUS_CALL( diff --git a/src/core/legacy_enum_definitions/4C_legacy_enum_definitions_materials.cpp b/src/core/legacy_enum_definitions/4C_legacy_enum_definitions_materials.cpp index c12a9dd8be3..a342a8a6e74 100644 --- a/src/core/legacy_enum_definitions/4C_legacy_enum_definitions_materials.cpp +++ b/src/core/legacy_enum_definitions/4C_legacy_enum_definitions_materials.cpp @@ -105,6 +105,8 @@ std::string_view Core::Materials::to_string(Core::Materials::MaterialType materi return "MAT_Struct_ThermoPlasticLinElast"; case m_superelast: return "MAT_Struct_SuperElastSMA"; + case m_superposition: + return "MAT_Solid_Superposition"; case m_thermoplhyperelast: return "MAT_Struct_ThermoPlasticHyperElast"; case m_plnlnlogneohooke: diff --git a/src/core/legacy_enum_definitions/4C_legacy_enum_definitions_materials.hpp b/src/core/legacy_enum_definitions/4C_legacy_enum_definitions_materials.hpp index fe4008d14da..e3805640d7f 100644 --- a/src/core/legacy_enum_definitions/4C_legacy_enum_definitions_materials.hpp +++ b/src/core/legacy_enum_definitions/4C_legacy_enum_definitions_materials.hpp @@ -177,6 +177,7 @@ namespace Core::Materials m_structpororeaction, ///< wrapper material for poroelasticity (structure) m_structpororeactionECM, ///< wrapper material for poroelasticity (structure) m_superelast, ///< Superelastic material behaviour of shape memory alloys + m_superposition, ///< material for superposition of multiple materials m_stvenant, ///< St.Venant Kirchhoff material m_orthostvenant, ///< St.Venant Kirchhoff material with orthotropy m_sutherland, ///< material with temperature dependence according to Sutherland law diff --git a/src/core/linalg/src/dense/4C_linalg_fixedsizematrix_tensor_products.cpp b/src/core/linalg/src/dense/4C_linalg_fixedsizematrix_tensor_products.cpp index 25eb203c53e..e0bd4ff6dbb 100644 --- a/src/core/linalg/src/dense/4C_linalg_fixedsizematrix_tensor_products.cpp +++ b/src/core/linalg/src/dense/4C_linalg_fixedsizematrix_tensor_products.cpp @@ -150,120 +150,6 @@ void Core::LinAlg::FourTensorOperations::add_kronecker_tensor_product(Core::LinA scalar_this * C(5, 5) + scalar_AB_half * (A(0, 0) * B(2, 2) + A(0, 2) * B(2, 0)); // C1313 } - -void Core::LinAlg::FourTensorOperations::add_kronecker_tensor_product(Core::LinAlg::Matrix<6, 9>& C, - const double scalar_AB, const Core::LinAlg::Matrix<3, 3>& A, - const Core::LinAlg::Matrix<3, 3>& B, const double scalar_this) -{ - const double scalar_AB_half = scalar_AB * 0.5; - C(0, 0) = scalar_this * C(0, 0) + scalar_AB * (A(0, 0) * B(0, 0)); // C1111 - C(0, 1) = scalar_this * C(0, 1) + scalar_AB * (A(0, 1) * B(0, 1)); // C1122 - C(0, 2) = scalar_this * C(0, 2) + scalar_AB * (A(0, 2) * B(0, 2)); // C1133 - C(0, 3) = - scalar_this * C(0, 3) + scalar_AB_half * (A(0, 0) * B(0, 1) + A(0, 1) * B(0, 0)); // C1112 - C(0, 4) = - scalar_this * C(0, 4) + scalar_AB_half * (A(0, 1) * B(0, 2) + A(0, 2) * B(0, 1)); // C1123 - C(0, 5) = - scalar_this * C(0, 5) + scalar_AB_half * (A(0, 0) * B(0, 2) + A(0, 2) * B(0, 0)); // C1113 - C(0, 6) = - scalar_this * C(0, 6) + scalar_AB_half * (A(0, 1) * B(0, 0) + A(0, 0) * B(0, 1)); // C1121 - C(0, 7) = - scalar_this * C(0, 7) + scalar_AB_half * (A(0, 2) * B(0, 1) + A(0, 1) * B(0, 2)); // C1132 - C(0, 8) = - scalar_this * C(0, 8) + scalar_AB_half * (A(0, 2) * B(0, 0) + A(0, 0) * B(0, 2)); // C1131 - - - C(1, 0) = scalar_this * C(1, 0) + scalar_AB * (A(1, 0) * B(1, 0)); // C2211 - C(1, 1) = scalar_this * C(1, 1) + scalar_AB * (A(1, 1) * B(1, 1)); // C2222 - C(1, 2) = scalar_this * C(1, 2) + scalar_AB * (A(1, 2) * B(1, 2)); // C2233 - C(1, 3) = - scalar_this * C(1, 3) + scalar_AB_half * (A(1, 0) * B(1, 1) + A(1, 1) * B(1, 0)); // C2212 - C(1, 4) = - scalar_this * C(1, 4) + scalar_AB_half * (A(1, 1) * B(1, 2) + A(1, 2) * B(1, 1)); // C2223 - C(1, 5) = - scalar_this * C(1, 5) + scalar_AB_half * (A(1, 0) * B(1, 2) + A(1, 2) * B(1, 0)); // C2213 - C(1, 6) = - scalar_this * C(1, 6) + scalar_AB_half * (A(1, 1) * B(1, 0) + A(1, 0) * B(1, 1)); // C2221 - C(1, 7) = - scalar_this * C(1, 7) + scalar_AB_half * (A(1, 2) * B(1, 1) + A(1, 1) * B(1, 2)); // C2232 - C(1, 8) = - scalar_this * C(1, 8) + scalar_AB_half * (A(1, 2) * B(1, 0) + A(1, 0) * B(1, 2)); // C2231 - - - - C(2, 0) = scalar_this * C(2, 0) + scalar_AB * (A(2, 0) * B(2, 0)); // C3311 - C(2, 1) = scalar_this * C(2, 1) + scalar_AB * (A(2, 1) * B(2, 1)); // C3322 - C(2, 2) = scalar_this * C(2, 2) + scalar_AB * (A(2, 2) * B(2, 2)); // C3333 - C(2, 3) = - scalar_this * C(2, 3) + scalar_AB_half * (A(2, 0) * B(2, 1) + A(2, 1) * B(2, 0)); // C3312 - C(2, 4) = - scalar_this * C(2, 4) + scalar_AB_half * (A(2, 1) * B(2, 2) + A(2, 2) * B(2, 1)); // C3323 - C(2, 5) = - scalar_this * C(2, 5) + scalar_AB_half * (A(2, 0) * B(2, 2) + A(2, 2) * B(2, 0)); // C3313 - C(2, 6) = - scalar_this * C(2, 6) + scalar_AB_half * (A(2, 0) * B(2, 1) + A(2, 1) * B(2, 0)); // C3321 - C(2, 7) = - scalar_this * C(2, 7) + scalar_AB_half * (A(2, 2) * B(2, 1) + A(2, 1) * B(2, 2)); // C3332 - C(2, 8) = - scalar_this * C(2, 8) + scalar_AB_half * (A(2, 2) * B(2, 0) + A(2, 0) * B(2, 2)); // C3331 - - - - C(3, 0) = scalar_this * C(3, 0) + scalar_AB * (A(0, 0) * B(1, 0)); // C1211 - C(3, 1) = scalar_this * C(3, 1) + scalar_AB * (A(0, 1) * B(1, 1)); // C1222 - C(3, 2) = scalar_this * C(3, 2) + scalar_AB * (A(0, 2) * B(1, 2)); // C1233 - C(3, 3) = - scalar_this * C(3, 3) + scalar_AB_half * (A(0, 0) * B(1, 1) + A(0, 1) * B(1, 0)); // C1212 - C(3, 4) = - scalar_this * C(3, 4) + scalar_AB_half * (A(0, 1) * B(1, 2) + A(0, 2) * B(1, 1)); // C1223 - C(3, 5) = - scalar_this * C(3, 5) + scalar_AB_half * (A(0, 0) * B(1, 2) + A(0, 2) * B(1, 0)); // C1213 - C(3, 6) = - scalar_this * C(3, 6) + scalar_AB_half * (A(0, 1) * B(1, 0) + A(0, 0) * B(1, 1)); // C1221 - C(3, 7) = - scalar_this * C(3, 7) + scalar_AB_half * (A(0, 2) * B(1, 1) + A(0, 1) * B(1, 2)); // C1232 - C(3, 8) = - scalar_this * C(3, 8) + scalar_AB_half * (A(0, 2) * B(1, 0) + A(0, 0) * B(1, 2)); // C1231 - - - - C(4, 0) = scalar_this * C(4, 0) + scalar_AB * (A(1, 0) * B(2, 0)); // C2311 - C(4, 1) = scalar_this * C(4, 1) + scalar_AB * (A(1, 1) * B(2, 1)); // C2322 - C(4, 2) = scalar_this * C(4, 2) + scalar_AB * (A(1, 2) * B(2, 2)); // C2333 - C(4, 3) = - scalar_this * C(4, 3) + scalar_AB_half * (A(1, 0) * B(2, 1) + A(1, 1) * B(2, 0)); // C2312 - C(4, 4) = - scalar_this * C(4, 4) + scalar_AB_half * (A(1, 1) * B(2, 2) + A(1, 2) * B(2, 1)); // C2323 - C(4, 5) = - scalar_this * C(4, 5) + scalar_AB_half * (A(1, 0) * B(2, 2) + A(1, 2) * B(2, 0)); // C2313 - C(4, 6) = - scalar_this * C(4, 6) + scalar_AB_half * (A(1, 1) * B(2, 0) + A(1, 0) * B(2, 1)); // C2321 - C(4, 7) = - scalar_this * C(4, 7) + scalar_AB_half * (A(1, 2) * B(2, 1) + A(1, 1) * B(2, 2)); // C2332 - C(4, 8) = - scalar_this * C(4, 8) + scalar_AB_half * (A(1, 2) * B(2, 0) + A(1, 0) * B(2, 2)); // C2331 - - - - C(5, 0) = scalar_this * C(5, 0) + scalar_AB * (A(0, 0) * B(2, 0)); // C1311 - C(5, 1) = scalar_this * C(5, 1) + scalar_AB * (A(0, 1) * B(2, 1)); // C1322 - C(5, 2) = scalar_this * C(5, 2) + scalar_AB * (A(0, 2) * B(2, 2)); // C1333 - C(5, 3) = - scalar_this * C(5, 3) + scalar_AB_half * (A(0, 0) * B(2, 1) + A(0, 1) * B(2, 0)); // C1312 - C(5, 4) = - scalar_this * C(5, 4) + scalar_AB_half * (A(0, 1) * B(2, 2) + A(0, 2) * B(2, 1)); // C1323 - C(5, 5) = - scalar_this * C(5, 5) + scalar_AB_half * (A(0, 0) * B(2, 2) + A(0, 2) * B(2, 0)); // C1313 - C(5, 5) = - scalar_this * C(5, 5) + scalar_AB_half * (A(0, 0) * B(2, 2) + A(0, 2) * B(2, 0)); // C1313 - C(5, 6) = - scalar_this * C(5, 6) + scalar_AB_half * (A(0, 1) * B(2, 0) + A(0, 0) * B(2, 1)); // C1321 - C(5, 7) = - scalar_this * C(5, 7) + scalar_AB_half * (A(0, 2) * B(2, 1) + A(0, 1) * B(2, 2)); // C1332 - C(5, 8) = - scalar_this * C(5, 7) + scalar_AB_half * (A(0, 2) * B(2, 0) + A(0, 0) * B(2, 2)); // C1331 -} - template void Core::LinAlg::FourTensorOperations::add_holzapfel_product( Core::LinAlg::Matrix<6, 6, T>& cmat, const Core::LinAlg::Matrix<6, 1, T>& invc, const T scalar) @@ -922,16 +808,6 @@ void Core::LinAlg::FourTensorOperations::add_contraction_matrix_four_tensor( matrix_result(i, j) += scale * four_tensor(i, j, k, l) * matrix(k, l); } -double Core::LinAlg::FourTensorOperations::contract_matrix_matrix( - const Core::LinAlg::Matrix<3, 3>& matrix_A, const Core::LinAlg::Matrix<3, 3>& matrix_B) -{ - double scalarContraction = 0.0; - for (unsigned i = 0; i < 3; ++i) - for (unsigned j = 0; j < 3; ++j) scalarContraction += matrix_A(i, j) * matrix_B(i, j); - - return scalarContraction; -} - // explicit instantiation of template functions template void Core::LinAlg::FourTensorOperations::add_holzapfel_product( Core::LinAlg::Matrix<6, 6, double>&, const Core::LinAlg::Matrix<6, 1, double>&, diff --git a/src/core/linalg/src/dense/4C_linalg_fixedsizematrix_tensor_products.hpp b/src/core/linalg/src/dense/4C_linalg_fixedsizematrix_tensor_products.hpp index ec7348595e7..57e0f57fbfe 100644 --- a/src/core/linalg/src/dense/4C_linalg_fixedsizematrix_tensor_products.hpp +++ b/src/core/linalg/src/dense/4C_linalg_fixedsizematrix_tensor_products.hpp @@ -21,7 +21,6 @@ #include "4C_linalg_four_tensor.hpp" #include "4C_linalg_symmetric_tensor.hpp" #include "4C_linalg_tensor.hpp" - FOUR_C_NAMESPACE_OPEN namespace Core::LinAlg::FourTensorOperations @@ -99,25 +98,6 @@ namespace Core::LinAlg::FourTensorOperations const Core::LinAlg::Matrix<3, 3>& A, const Core::LinAlg::Matrix<3, 3>& B, const double scalar_this); - /*! - * @brief Multiply two 2nd order tensors A o B and add the result to a 4th order material tensor - * in matrix notation, possessing left minor symmetry. - * - * In tensor index notation this method does - * \f[ - * C_{IJKL} := \text{scalar_this} \cdot C_{IJKL} + \frac{1}{2} \cdot \text{scalar_AB} \cdot \left( - * A_{IK} \cdot B_{JL} + A_{IL} \cdot B_{JK} \right) \f] - * - * - * @param[in,out] C Material tangent matrix to be modified - * @param[in] scalar_AB Scalar to multiply with A o B - * @param[in] A Dense matrix (3 x 3) as 2nd order tensor A - * @param[in] B Dense matrix (3 x 3) as 2nd order tensor B - * @param[in] scalar_this Scalar to multiply with C before adding A o B - */ - void add_kronecker_tensor_product(Core::LinAlg::Matrix<6, 9>& C, const double scalar_AB, - const Core::LinAlg::Matrix<3, 3>& A, const Core::LinAlg::Matrix<3, 3>& B, - const double scalar_this); /*! @@ -445,16 +425,6 @@ namespace Core::LinAlg::FourTensorOperations const double scale, const Core::LinAlg::FourTensor<3>& four_tensor, const Core::LinAlg::Matrix<3, 3>& matrix); - /*! - * @brief Returns the double contraction of two 2nd order tensors - * - * @param[out] scalarContraction 0th order tensor \f$s = A_{ij} B^{ij}\f$ - * @param[in] matrix_A 2nd order tensor \f$A_{ij}\f$ - * @param[in] matrix_B 2nd order tensor \f$B^{ij}\f$ - */ - double contract_matrix_matrix( - const Core::LinAlg::Matrix<3, 3>& matrix_A, const Core::LinAlg::Matrix<3, 3>& matrix_B); - } // namespace Core::LinAlg::FourTensorOperations diff --git a/src/core/linalg/src/dense/4C_linalg_tensor_conversion.hpp b/src/core/linalg/src/dense/4C_linalg_tensor_conversion.hpp index da917e4e58c..3c8140cfe36 100644 --- a/src/core/linalg/src/dense/4C_linalg_tensor_conversion.hpp +++ b/src/core/linalg/src/dense/4C_linalg_tensor_conversion.hpp @@ -15,6 +15,7 @@ #include "4C_linalg_tensor.hpp" #include "4C_linalg_tensor_internals.hpp" +#include #include #include #include @@ -226,6 +227,89 @@ namespace Core::LinAlg } } + /*! + * @brief Creates a 6x9 Voigt matrix from a 4th order tensor that has the minor symmetry in its + * first index pair (C_ijkl = C_jikl). + * + * The first (symmetric) index pair is stored in stress-like 6-Voigt notation, the second + * (non-symmetric) index pair as a 9-vector. + */ + template + Core::LinAlg::Matrix<6, 9, T> make_6x9_voigt_matrix_from_tensor( + const Core::LinAlg::Tensor& tensor) + { + constexpr std::array, 6> row_index = { + {{0, 0}, {1, 1}, {2, 2}, {0, 1}, {1, 2}, {0, 2}}}; + constexpr std::array, 9> col_index = { + {{0, 0}, {1, 1}, {2, 2}, {0, 1}, {1, 2}, {0, 2}, {1, 0}, {2, 1}, {2, 0}}}; + + Core::LinAlg::Matrix<6, 9, T> matrix_voigt; + for (std::size_t r = 0; r < 6; ++r) + { + for (std::size_t c = 0; c < 9; ++c) + { + matrix_voigt(r, c) = + 0.5 * (tensor(row_index[r][0], row_index[r][1], col_index[c][0], col_index[c][1]) + + tensor(row_index[r][1], row_index[r][0], col_index[c][0], col_index[c][1])); + } + } + return matrix_voigt; + } + + /*! + * @brief Creates a 9x6 Voigt matrix from a 4th order tensor that has the minor symmetry in its + * second index pair (C_ijkl = C_ijlk). + * + * The first (non-symmetric) index pair is stored as a 9-vector, the second (symmetric) index + * pair in stress-like 6-Voigt notation. + */ + template + Core::LinAlg::Matrix<9, 6, T> make_9x6_voigt_matrix_from_tensor( + const Core::LinAlg::Tensor& tensor) + { + constexpr std::array, 9> row_index = { + {{0, 0}, {1, 1}, {2, 2}, {0, 1}, {1, 2}, {0, 2}, {1, 0}, {2, 1}, {2, 0}}}; + constexpr std::array, 6> col_index = { + {{0, 0}, {1, 1}, {2, 2}, {0, 1}, {1, 2}, {0, 2}}}; + + Core::LinAlg::Matrix<9, 6, T> matrix_voigt; + for (std::size_t r = 0; r < 9; ++r) + { + for (std::size_t c = 0; c < 6; ++c) + { + matrix_voigt(r, c) = + 0.5 * (tensor(row_index[r][0], row_index[r][1], col_index[c][0], col_index[c][1]) + + tensor(row_index[r][0], row_index[r][1], col_index[c][1], col_index[c][0])); + } + } + return matrix_voigt; + } + + /*! + * @brief Creates a 6x6 stress-like Voigt matrix from a (minor-)symmetric 4th order tensor. + * + * The minor symmetries (IJ) and (KL) are encoded in the symmetric tensor, so its components map + * directly to stress-like 6-Voigt notation. The result may still be a non-symmetric 6x6 matrix + * if the tensor lacks major symmetry (C_IJKL != C_KLIJ). + */ + template + Core::LinAlg::Matrix<6, 6, T> make_6x6_voigt_matrix_from_tensor( + const Core::LinAlg::SymmetricTensor& tensor) + { + constexpr std::array, 6> vi = { + {{0, 0}, {1, 1}, {2, 2}, {0, 1}, {1, 2}, {0, 2}}}; + + Core::LinAlg::Matrix<6, 6, T> result; + for (std::size_t r = 0; r < 6; ++r) + { + for (std::size_t c = 0; c < 6; ++c) + { + result(r, c) = tensor(vi[r][0], vi[r][1], vi[c][0], vi[c][1]); + } + } + return result; + } + /*! * @brief Creates a strain-like Voigt notation matrix from a symmetric tensor. * diff --git a/src/core/linalg/tests/4C_linalg_tensor_conversion_test.cpp b/src/core/linalg/tests/4C_linalg_tensor_conversion_test.cpp index d124bfe7013..a2f7740713f 100644 --- a/src/core/linalg/tests/4C_linalg_tensor_conversion_test.cpp +++ b/src/core/linalg/tests/4C_linalg_tensor_conversion_test.cpp @@ -12,6 +12,7 @@ #include "4C_linalg_tensor_conversion.hpp" #include "4C_linalg_fixedsizematrix.hpp" +#include "4C_linalg_fixedsizematrix_tensor_products.hpp" #include "4C_linalg_symmetric_tensor.hpp" #include "4C_linalg_symmetric_tensor_eigen.hpp" #include "4C_linalg_tensor_generators.hpp" @@ -314,6 +315,82 @@ namespace EXPECT_DOUBLE_EQ(nested_array[1][1], 4.0); EXPECT_DOUBLE_EQ(nested_array[2][1], 6.0); } + TEST(TensorConversionTest, Make6x9VoigtMatrixFromTensorTest) + { + // arbitrary (non-symmetric) 4th order tensor; both paths apply the same 1st-pair symmetrization + Core::LinAlg::Tensor T{}; + Core::LinAlg::FourTensor<3> ft(true); + int v = 1; + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 3; ++k) + for (int l = 0; l < 3; ++l) + { + const double val = 0.1 * (v++); + T(i, j, k, l) = val; + ft(i, j, k, l) = val; + } + + const Core::LinAlg::Matrix<6, 9> new_voigt = Core::LinAlg::make_6x9_voigt_matrix_from_tensor(T); + Core::LinAlg::Matrix<6, 9> old_voigt(Core::LinAlg::Initialization::zero); + Core::LinAlg::Voigt::setup_6x9_voigt_matrix_from_four_tensor(old_voigt, ft); + + FOUR_C_EXPECT_NEAR(new_voigt, old_voigt, 1e-12); + } + + TEST(TensorConversionTest, Make9x6VoigtMatrixFromTensorTest) + { + // arbitrary (non-symmetric) 4th order tensor; both paths apply the same 2nd-pair symmetrization + Core::LinAlg::Tensor T{}; + Core::LinAlg::FourTensor<3> ft(true); + int v = 1; + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 3; ++k) + for (int l = 0; l < 3; ++l) + { + const double val = 0.1 * (v++); + T(i, j, k, l) = val; + ft(i, j, k, l) = val; + } + + const Core::LinAlg::Matrix<9, 6> new_voigt = Core::LinAlg::make_9x6_voigt_matrix_from_tensor(T); + Core::LinAlg::Matrix<9, 6> old_voigt(Core::LinAlg::Initialization::zero); + Core::LinAlg::Voigt::setup_9x6_voigt_matrix_from_four_tensor(old_voigt, ft); + + FOUR_C_EXPECT_NEAR(new_voigt, old_voigt, 1e-12); + } + + TEST(TensorConversionTest, Make6x6StressLikeVoigtMatrixFromTensorTest) + { + Core::LinAlg::Matrix<3, 3> A; + A(0, 0) = 1.0; + A(0, 1) = 2.0; + A(0, 2) = 3.0; + A(1, 0) = 0.5; + A(1, 1) = 4.0; + A(1, 2) = 1.2; + A(2, 0) = 7.0; + A(2, 1) = 0.3; + A(2, 2) = 6.0; + + Core::LinAlg::Tensor C_full{}; + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 3; ++k) + for (int l = 0; l < 3; ++l) + C_full(i, j, k, l) = 0.5 * (A(i, k) * A(j, l) + A(i, l) * A(j, k)); + const Core::LinAlg::SymmetricTensor C = + Core::LinAlg::assume_symmetry(C_full); + + const Core::LinAlg::Matrix<6, 6> result = Core::LinAlg::make_6x6_voigt_matrix_from_tensor(C); + + // reference: add_kronecker_tensor_product called on non-symmetric matrix + Core::LinAlg::Matrix<6, 6> ref(Core::LinAlg::Initialization::zero); + Core::LinAlg::FourTensorOperations::add_kronecker_tensor_product(ref, 1.0, A, A, 0.0); + + FOUR_C_EXPECT_NEAR(result, ref, 1e-12); + } } // namespace FOUR_C_NAMESPACE_CLOSE \ No newline at end of file diff --git a/src/global_legacy_module/4C_global_legacy_module.cpp b/src/global_legacy_module/4C_global_legacy_module.cpp index 3e1ca3dc422..2b40ba75b0b 100644 --- a/src/global_legacy_module/4C_global_legacy_module.cpp +++ b/src/global_legacy_module/4C_global_legacy_module.cpp @@ -92,6 +92,7 @@ #include "4C_mat_scatra_multiporo.hpp" #include "4C_mat_scatra_poro_ecm.hpp" #include "4C_mat_shell_kl.hpp" +#include "4C_mat_solid_superposition.hpp" #include "4C_mat_spring.hpp" #include "4C_mat_structporo.hpp" #include "4C_mat_structporo_reaction.hpp" @@ -243,6 +244,7 @@ namespace << Mat::StVenantKirchhoffType::instance().name() << " " << Mat::LinElast1DType::instance().name() << " " << Mat::LinElast1DGrowthType::instance().name() << " " + << Mat::SolidSuperpositionType::instance().name() << " " << Mat::SutherlandType::instance().name() << " " << Mat::ThermoStVenantKirchhoffType::instance().name() << " " << Mat::ThermoPlasticLinElastType::instance().name() << " " diff --git a/src/global_legacy_module/4C_global_legacy_module_validmaterials.cpp b/src/global_legacy_module/4C_global_legacy_module_validmaterials.cpp index ee5e2145361..684ca47e0a5 100644 --- a/src/global_legacy_module/4C_global_legacy_module_validmaterials.cpp +++ b/src/global_legacy_module/4C_global_legacy_module_validmaterials.cpp @@ -11,6 +11,7 @@ #include "4C_inpar_structure.hpp" #include "4C_io_input_field.hpp" #include "4C_io_input_spec_builders.hpp" +#include "4C_io_input_spec_storage.hpp" #include "4C_io_input_spec_validators.hpp" #include "4C_linalg_tensor_generators.hpp" #include "4C_linalg_utils_densematrix_funct.hpp" @@ -1292,6 +1293,26 @@ std::unordered_map Global::v {.description = "finite strain superelastic shape memory alloy"}); } + /*----------------------------------------------------------------------*/ + // 3D solid material superposition + { + using namespace Core::IO::InputSpecBuilders::Validators; + + known_materials[Core::Materials::m_superposition] = group("MAT_Solid_Superposition", + { + parameter>("MATIDS", + { + .description = "List of material IDs to be superimposed", + .validator = all_elements(positive()), + }), + parameter("DENS", {.description = "mass density of superposition material"}), + }, + {.description = + "3D solid material superposition. Each constituent material defined by " + "MATIDS is evaluated independently, and its responses are accumulated, " + "such that the stress S = sum_i S_i and the material tangent C = sum_i C_i"}); + } + /*----------------------------------------------------------------------*/ // Thermo-hyperelasticity / finite strain von-Mises plasticity { @@ -2814,6 +2835,8 @@ std::unordered_map Global::v /*----------------------------------------------------------------------*/ { using namespace Core::IO::InputSpecBuilders::Validators; + namespace ViscoplastUtils = Mat::InelasticDefgradTransvIsotropElastViscoplastUtils; + known_materials[Core::Materials::mfi_transv_isotrop_elast_viscoplast] = group( "MAT_InelasticDefgradTransvIsotropElastViscoplast", {parameter( @@ -2843,34 +2866,19 @@ std::unordered_map Global::v "yield condition: parameter F, following the " "notation in Dafalias 1989, International " "Journal of Plasticity, Vol. 5"}), - parameter( + parameter( "MAT_BEHAVIOR", {.description = "Material behavior / anisotropy type"}), - parameter( - "TIME_INTEGRATION_HIST_VARS", + parameter("TIME_INTEGRATION_HIST_VARS", {.description = "time integration of internal variables: standard | logarithmic " "(logarithmic transformation of the " "evolution equation for the plastic deformation gradient -> default)", - .default_value = Mat::InelasticDefgradTransvIsotropElastViscoplastUtils:: - TimIntType::logarithmic}), - parameter( - "LINEARIZATION", + .default_value = ViscoplastUtils::TimIntType::logarithmic}), + parameter("LINEARIZATION", {.description = "utilized material linearization: analytic | perturb_based (based on " "perturbations of the current state)", - .default_value = Mat::InelasticDefgradTransvIsotropElastViscoplastUtils:: - LinearizationType::analytic}), - parameter("MAX_PLASTIC_STRAIN_INCR", - {.description = "maximum evaluable plastic strain increment " - "used for verifying overflow errors", - .default_value = std::exp(30.0), - .validator = positive()}), - parameter("MAX_PLASTIC_STRAIN_DERIV_INCR", - {.description = "maximum evaluable increment of the plastic strain derivatives " - "w.r.t. plastic strain and equivalent stress, used for verifying " - "possible overflow errors", - .default_value = std::exp(30.0), - .validator = positive()}), + .default_value = ViscoplastUtils::LinearizationType::analytic}), parameter("MATRIX_EXP_CALC_METHOD", {.description = "chosen computation method for matrix exponential (default: " "automatic method selection based on matrix characteristics)", @@ -2903,20 +2911,22 @@ std::unordered_map Global::v {.description = "Settings for the usage of local substepping to integrate the " "viscoplastic evolution equations", .required = false}), - group("LOCAL_NEWTON", - {parameter< - Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvCheck>( - "CONV_CHECK", + group("LOCAL_NEWTON", + {parameter("CONV_CHECK", {.description = "convergence check type", - .default_value = Mat::InelasticDefgradTransvIsotropElastViscoplastUtils:: - LocalNewtonConvCheck::residual_and_increment_ratio}), - parameter("MAX_ITER", {.description = "maximum number of iterations", - .default_value = 100, - .validator = positive()}), - parameter( - "RES_TOL", {.description = "residual tolerance (absolute residual 2-norm)", - .default_value = 1.0e-8, - .validator = positive()}), + .default_value = + ViscoplastUtils::LocalNewtonConvCheck::residual_and_increment_ratio, + .store = in_struct(&ViscoplastUtils::LocalNewtonParams::conv_check)}), + parameter("MAX_ITER", + {.description = "maximum number of iterations", + .default_value = 100, + .validator = positive(), + .store = in_struct(&ViscoplastUtils::LocalNewtonParams::max_iter)}), + parameter("RES_TOL", + {.description = "residual tolerance (absolute residual 2-norm)", + .default_value = 1.0e-8, + .validator = positive(), + .store = in_struct(&ViscoplastUtils::LocalNewtonParams::res_tol)}), parameter("MAX_EXCEEDANCE_FACT_RES_TOL", {.description = "maximum exceedance factor for the specified residual tolerance " @@ -2924,12 +2934,17 @@ std::unordered_map Global::v "continuing the simulation, if specified by the user via " "DIVER_CONT)", .default_value = 1.0e1, - .validator = positive_or_zero()}), - parameter( - "INCR_TOL", {.description = "increment tolerance (" - "ratio of |increment| / |solution|)", - .default_value = 1.0e-8, - .validator = positive()}), + .validator = positive_or_zero(), + .store = in_struct( + &ViscoplastUtils::LocalNewtonParams::max_exceedance_fact_res_tol)}), + parameter("INCR_TOL", + {.description = "increment tolerance (" + "ratio of |increment| / |solution|)", + .default_value = 1.0e-8, + .validator = positive(), + .store = in_struct(&ViscoplastUtils::LocalNewtonParams::incr_tol) + + }), parameter("MAX_EXCEEDANCE_FACT_INCR_TOL", {.description = "maximum exceedance factor for the specified increment tolerance " @@ -2937,17 +2952,54 @@ std::unordered_map Global::v "continuing the simulation, if specified by the user via " "DIVER_CONT)", .default_value = 1.0e1, - .validator = positive_or_zero()}), - parameter("DIVER_CONT", + .validator = positive_or_zero(), + .store = in_struct( + &ViscoplastUtils::LocalNewtonParams::max_exceedance_fact_incr_tol) + + }), + parameter("DIVER_CONT", {.description = "strategy to deal with divergence in the Local Newton Loop", - .default_value = - Mat::InelasticDefgradTransvIsotropElastViscoplastUtils:: - LocalNewtonDiverCont::stop}) + .default_value = ViscoplastUtils::LocalNewtonDiverCont::stop, + .store = in_struct(&ViscoplastUtils::LocalNewtonParams::diver_cont) + + }) }, {.description = "Parameters used in the Local Newton--Raphson procedure " "(viscoplastic corrector stage)", + .required = false}), + group("ERROR_REGISTRATION_SETTINGS", + {parameter("REGISTER_PLASTIC_STRAIN_INCR_OVERFLOW", + {.description = "should overflow error be registered via ErrorType when the " + "plastic strain increment exceeds the specified tolerance?", + .default_value = true, + .store = in_struct(&ViscoplastUtils::ErrorRegistrationSettings:: + register_plastic_strain_incr_overflow)}), + parameter("MAX_PLASTIC_STRAIN_INCR", + {.description = "maximum evaluable plastic strain increment " + "used for registering overflow errors", + .default_value = std::exp(30.0), + .validator = positive(), + .store = in_struct(&ViscoplastUtils::ErrorRegistrationSettings:: + max_plastic_strain_incr)}), + parameter("REGISTER_PLASTIC_STRAIN_DERIV_INCR_OVERFLOW", + {.description = "should overflow error be registered via ErrorType when " + "any of the plastic strain derivative increments exceeds " + "the specified tolerance?", + .default_value = false, + .store = in_struct(&ViscoplastUtils::ErrorRegistrationSettings:: + register_plastic_strain_deriv_incr_overflow)}), + parameter("MAX_PLASTIC_STRAIN_DERIV_INCR", + {.description = "maximum evaluable increment of the plastic strain " + "derivatives w.r.t. plastic strain and equivalent " + "stress, used for registering " + "overflow errors", + .default_value = std::exp(30.0), + .validator = positive(), + .store = in_struct(&ViscoplastUtils::ErrorRegistrationSettings:: + max_plastic_strain_deriv_incr)})}, + {.description = "Settings for registering errors within the procedures used for " + "constitutive update", .required = false})}, {.description = "Versatile transversely isotropic (or isotropic) viscoplasticity model for " "finite deformations with isotropic hardening, using user-defined " diff --git a/src/mat/4C_mat_aaaneohooke.cpp b/src/mat/4C_mat_aaaneohooke.cpp index 48457c2054c..0c82cef0df3 100644 --- a/src/mat/4C_mat_aaaneohooke.cpp +++ b/src/mat/4C_mat_aaaneohooke.cpp @@ -387,4 +387,4 @@ bool Mat::AAAneohooke::vis_data( return true; } -FOUR_C_NAMESPACE_CLOSE +FOUR_C_NAMESPACE_CLOSE \ No newline at end of file diff --git a/src/mat/4C_mat_aaaneohooke.hpp b/src/mat/4C_mat_aaaneohooke.hpp index 7df8f9ab839..281e928e4a8 100644 --- a/src/mat/4C_mat_aaaneohooke.hpp +++ b/src/mat/4C_mat_aaaneohooke.hpp @@ -152,17 +152,8 @@ namespace Mat //@} /// material mass density - // virtual double Density() const { return params_->GetDensity(); } double density() const override { return params_->get_parameter(params_->density, -1); } - /// shear modulus - // double shear_mod() const { return 0.5*params_->GetYoungs(-1)/(1.0+params_->GetNue()); } - double shear_mod() const - { - return 0.5 * params_->get_parameter(params_->young, -1) / - (1.0 + params_->get_parameter(params_->nue, -1)); - } - // material type Core::Materials::MaterialType material_type() const override { diff --git a/src/mat/4C_mat_anisotropy.cpp b/src/mat/4C_mat_anisotropy.cpp index fa09f0d5a4a..3d0da62b332 100644 --- a/src/mat/4C_mat_anisotropy.cpp +++ b/src/mat/4C_mat_anisotropy.cpp @@ -57,6 +57,10 @@ void Mat::Anisotropy::pack_anisotropy(Core::Communication::PackBuffer& data) con void Mat::Anisotropy::unpack_anisotropy(Core::Communication::UnpackBuffer& buffer) { + // Extensions are external references that are not packed. The summands that own them + // may be recreated during unpack, so clear the stale references before re-registration. + extensions_.clear(); + extract_from_pack(buffer, numgp_); extract_from_pack(buffer, element_fibers_initialized_); extract_from_pack(buffer, gp_fibers_initialized_); @@ -227,7 +231,6 @@ const Core::LinAlg::Tensor& Mat::Anisotropy::get_gauss_point_fiber( void Mat::Anisotropy::register_anisotropy_extension(BaseAnisotropyExtension& extension) { extensions_.emplace_back(Core::Utils::shared_ptr_from_ref(extension)); - extension.set_anisotropy(*this); } void Mat::Anisotropy::on_element_fibers_initialized() @@ -235,14 +238,14 @@ void Mat::Anisotropy::on_element_fibers_initialized() element_fibers_initialized_ = true; for (auto& extension : extensions_) { - extension->on_global_element_data_initialized(); + extension->on_global_element_data_initialized(*this); } if (element_fibers_initialized_ and gp_fibers_initialized_) { for (auto& extension : extensions_) { - extension->on_global_data_initialized(); + extension->on_global_data_initialized(*this); } } } @@ -252,14 +255,14 @@ void Mat::Anisotropy::on_gp_fibers_initialized() gp_fibers_initialized_ = true; for (auto& extension : extensions_) { - extension->on_global_gp_data_initialized(); + extension->on_global_gp_data_initialized(*this); } if (element_fibers_initialized_ and gp_fibers_initialized_) { for (auto& extension : extensions_) { - extension->on_global_data_initialized(); + extension->on_global_data_initialized(*this); } } } diff --git a/src/mat/4C_mat_anisotropy_extension.cpp b/src/mat/4C_mat_anisotropy_extension.cpp index c9d0b36e4a7..e38e3c12e42 100644 --- a/src/mat/4C_mat_anisotropy_extension.cpp +++ b/src/mat/4C_mat_anisotropy_extension.cpp @@ -37,11 +37,11 @@ template void Mat::FiberAnisotropyExtension::set_fibers( int gp, const std::array, numfib>& fibers) { - if (gp >= get_anisotropy()->get_number_of_gauss_points()) + if (gp >= numgp_) { FOUR_C_THROW( "The current Gauss point {} is out of range of the expected number of Gauss points {}.", gp, - get_anisotropy()->get_number_of_gauss_points()); + numgp_); } if (fibers_.empty()) @@ -130,6 +130,7 @@ template void Mat::FiberAnisotropyExtension::pack_anisotropy( Core::Communication::PackBuffer& data) const { + add_to_pack(data, numgp_); add_to_pack(data, fibers_); add_to_pack(data, fiber_structural_tensors_); add_to_pack(data, tensor_flags_); @@ -140,6 +141,7 @@ template void Mat::FiberAnisotropyExtension::unpack_anisotropy( Core::Communication::UnpackBuffer& buffer) { + extract_from_pack(buffer, numgp_); extract_from_pack(buffer, fibers_); extract_from_pack(buffer, fiber_structural_tensors_); extract_from_pack(buffer, tensor_flags_); @@ -171,7 +173,7 @@ int Mat::FiberAnisotropyExtension::get_fibers_per_element() const return 1; } - return get_anisotropy()->get_number_of_gauss_points(); + return numgp_; } // explicit instantiations of template classes diff --git a/src/mat/4C_mat_anisotropy_extension.hpp b/src/mat/4C_mat_anisotropy_extension.hpp index 857e9bf2aed..6c8e30ed90e 100644 --- a/src/mat/4C_mat_anisotropy_extension.hpp +++ b/src/mat/4C_mat_anisotropy_extension.hpp @@ -58,9 +58,6 @@ namespace Mat template class FiberAnisotropyExtension : public BaseAnisotropyExtension, public FiberProvider { - // Anisotropy is a friend to create back reference - friend class Anisotropy; - public: //! @name Tensors needed for the evaluation /// @{ @@ -193,7 +190,7 @@ namespace Mat * \return true if the fibers are initialized * \return false if the fibers are not initialized */ - virtual bool do_element_fiber_initialization() { return false; } + virtual bool do_element_fiber_initialization(Anisotropy& /*anisotropy*/) { return false; } /*! * \brief Method that initialized Gauss point fibers. @@ -203,7 +200,7 @@ namespace Mat * \return true if the fibers are initialized * \return false if the fibers are not initialized */ - virtual bool do_gp_fiber_initialization() { return false; } + virtual bool do_gp_fiber_initialization(Anisotropy& /*anisotropy*/) { return false; } /*! * \brief Method that will be called of the fibers are initialized. @@ -231,16 +228,20 @@ namespace Mat * \brief This method will be called by Mat::Anisotropy if element and Gauss point fibers are * available */ - void on_global_data_initialized() override {} + void on_global_data_initialized(Anisotropy& anisotropy) override + { + numgp_ = anisotropy.get_number_of_gauss_points(); + } private: /*! * \brief This method will be called by Mat::Anisotropy to notify that element information is * available. */ - void on_global_element_data_initialized() override + void on_global_element_data_initialized(Anisotropy& anisotropy) override { - const bool initialized = do_element_fiber_initialization(); + numgp_ = anisotropy.get_number_of_gauss_points(); + const bool initialized = do_element_fiber_initialization(anisotropy); if (initialized) on_fibers_initialized(); } @@ -248,9 +249,10 @@ namespace Mat * \brief This method will be called by Mat::Anisotropy to notify that Gauss point information * is available. */ - void on_global_gp_data_initialized() override + void on_global_gp_data_initialized(Anisotropy& anisotropy) override { - const bool initialized = do_gp_fiber_initialization(); + numgp_ = anisotropy.get_number_of_gauss_points(); + const bool initialized = do_gp_fiber_initialization(anisotropy); if (initialized) on_fibers_initialized(); } /// \} @@ -266,6 +268,9 @@ namespace Mat */ void compute_structural_tensors_stress(); + /// Number of Gauss points supplied by the Anisotropy class during setup + int numgp_ = -1; + /// Indication of the fiber location FiberLocation fiber_location_ = FiberLocation::None; diff --git a/src/mat/4C_mat_anisotropy_extension_base.cpp b/src/mat/4C_mat_anisotropy_extension_base.cpp deleted file mode 100644 index 564fee17f99..00000000000 --- a/src/mat/4C_mat_anisotropy_extension_base.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// This file is part of 4C multiphysics licensed under the -// GNU Lesser General Public License v3.0 or later. -// -// See the LICENSE.md file in the top-level for license information. -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#include "4C_mat_anisotropy_extension_base.hpp" - -#include "4C_comm_pack_helpers.hpp" -#include "4C_mat_anisotropy.hpp" -#include "4C_utils_shared_ptr_from_ref.hpp" - -FOUR_C_NAMESPACE_OPEN - -void Mat::BaseAnisotropyExtension::set_anisotropy(Mat::Anisotropy& anisotropy) -{ - anisotropy_ = Core::Utils::shared_ptr_from_ref(anisotropy); -} - -FOUR_C_NAMESPACE_CLOSE diff --git a/src/mat/4C_mat_anisotropy_extension_base.hpp b/src/mat/4C_mat_anisotropy_extension_base.hpp index 349a21b8f5f..782d0387d96 100644 --- a/src/mat/4C_mat_anisotropy_extension_base.hpp +++ b/src/mat/4C_mat_anisotropy_extension_base.hpp @@ -10,7 +10,6 @@ #include "4C_config.hpp" -#include #include FOUR_C_NAMESPACE_OPEN @@ -28,7 +27,8 @@ namespace Mat class BaseAnisotropyExtension { - // Anisotropy is a friend to create back reference + // Anisotropy calls the private notification methods on_global_element_data_initialized + // and on_global_gp_data_initialized. friend class Anisotropy; public: @@ -57,48 +57,21 @@ namespace Mat * \brief This method will be called by Mat::Anisotropy if element and Gauss point fibers are * available */ - virtual void on_global_data_initialized() = 0; - - protected: - /*! - * \brief Returns the reference to the anisotropy - * - * \return std::shared_ptr& Reference to the anisotropy - */ - std::shared_ptr& get_anisotropy() { return anisotropy_; } - /*! - * \brief Returns the reference to the anisotropy - * - * \return std::shared_ptr& Reference to the anisotropy - */ - const std::shared_ptr& get_anisotropy() const { return anisotropy_; } + virtual void on_global_data_initialized(Anisotropy& anisotropy) = 0; private: /*! * \brief This method will be called by Mat::Anisotropy to notify that element information is * available. */ - virtual void on_global_element_data_initialized() = 0; + virtual void on_global_element_data_initialized(Anisotropy& anisotropy) = 0; /*! * \brief This method will be called by Mat::Anisotropy to notify that Gauss point information * is available. */ - virtual void on_global_gp_data_initialized() = 0; - - /// \name Private methods called by the friend class Mat::Anisotropy - /// \{ - /*! - * \brief Set the anisotropy. This method will only be used by Anisotropy itself to give the - * extension access to all anisotropy information. - * - * \param anisotropy - */ - void set_anisotropy(Anisotropy& anisotropy); - - /// Reference to Anisotropy - std::shared_ptr anisotropy_; + virtual void on_global_gp_data_initialized(Anisotropy& anisotropy) = 0; }; } // namespace Mat FOUR_C_NAMESPACE_CLOSE diff --git a/src/mat/4C_mat_anisotropy_extension_cylinder_cosy.cpp b/src/mat/4C_mat_anisotropy_extension_cylinder_cosy.cpp index 8ba4a85a9cd..0d6dc6cfce4 100644 --- a/src/mat/4C_mat_anisotropy_extension_cylinder_cosy.cpp +++ b/src/mat/4C_mat_anisotropy_extension_cylinder_cosy.cpp @@ -11,6 +11,7 @@ #include "4C_comm_parobject.hpp" #include "4C_mat_anisotropy.hpp" #include "4C_mat_anisotropy_coordinate_system_provider.hpp" +#include "4C_utils_exceptions.hpp" #include "4C_utils_shared_ptr_from_ref.hpp" FOUR_C_NAMESPACE_OPEN @@ -24,23 +25,34 @@ void Mat::CylinderCoordinateSystemAnisotropyExtension::pack_anisotropy( Core::Communication::PackBuffer& data) const { add_to_pack(data, cosy_location_); + add_to_pack(data, element_cosy_); + add_to_pack(data, gp_cosy_); } void Mat::CylinderCoordinateSystemAnisotropyExtension::unpack_anisotropy( Core::Communication::UnpackBuffer& buffer) { extract_from_pack(buffer, cosy_location_); + extract_from_pack(buffer, element_cosy_); + extract_from_pack(buffer, gp_cosy_); } -void Mat::CylinderCoordinateSystemAnisotropyExtension::on_global_data_initialized() +void Mat::CylinderCoordinateSystemAnisotropyExtension::on_global_data_initialized( + Mat::Anisotropy& anisotropy) { - if (get_anisotropy()->has_gp_cylinder_coordinate_system()) + if (anisotropy.has_gp_cylinder_coordinate_system()) { cosy_location_ = CosyLocation::GPCosy; + gp_cosy_.clear(); + for (int gp = 0; gp < anisotropy.get_number_of_gauss_points(); ++gp) + { + gp_cosy_.push_back(anisotropy.get_gp_cylinder_coordinate_system(gp)); + } } - else if (get_anisotropy()->has_element_cylinder_coordinate_system()) + else if (anisotropy.has_element_cylinder_coordinate_system()) { cosy_location_ = CosyLocation::ElementCosy; + element_cosy_ = anisotropy.get_element_cylinder_coordinate_system(); } else { @@ -48,14 +60,16 @@ void Mat::CylinderCoordinateSystemAnisotropyExtension::on_global_data_initialize } } -void Mat::CylinderCoordinateSystemAnisotropyExtension::on_global_element_data_initialized() +void Mat::CylinderCoordinateSystemAnisotropyExtension::on_global_element_data_initialized( + Mat::Anisotropy& anisotropy) { - // do nothing + (void)anisotropy; } -void Mat::CylinderCoordinateSystemAnisotropyExtension::on_global_gp_data_initialized() +void Mat::CylinderCoordinateSystemAnisotropyExtension::on_global_gp_data_initialized( + Mat::Anisotropy& anisotropy) { - // do nothing + (void)anisotropy; } const Mat::CylinderCoordinateSystemProvider& @@ -68,10 +82,14 @@ Mat::CylinderCoordinateSystemAnisotropyExtension::get_cylinder_coordinate_system if (cosy_location_ == CosyLocation::ElementCosy) { - return get_anisotropy()->get_element_cylinder_coordinate_system(); + FOUR_C_ASSERT(element_cosy_.has_value(), + "Invalid state: CosyLocation=ElementCosy, but element_cosy_ is empty. " + "Check initialization in on_global_data_initialized()."); + + return *element_cosy_; } - return get_anisotropy()->get_gp_cylinder_coordinate_system(gp); + return gp_cosy_.at(gp); } std::shared_ptr diff --git a/src/mat/4C_mat_anisotropy_extension_cylinder_cosy.hpp b/src/mat/4C_mat_anisotropy_extension_cylinder_cosy.hpp index 4ddd4398edd..7c245a6fefe 100644 --- a/src/mat/4C_mat_anisotropy_extension_cylinder_cosy.hpp +++ b/src/mat/4C_mat_anisotropy_extension_cylinder_cosy.hpp @@ -10,9 +10,11 @@ #include "4C_config.hpp" +#include "4C_mat_anisotropy_cylinder_coordinate_system_manager.hpp" #include "4C_mat_anisotropy_extension_base.hpp" - +#include +#include FOUR_C_NAMESPACE_OPEN @@ -66,7 +68,7 @@ namespace Mat * \brief This method will be called by Mat::Anisotropy if element and Gauss point fibers are * available */ - void on_global_data_initialized() override; + void on_global_data_initialized(Anisotropy& anisotropy) override; /*! * \brief Returns the cylinder coordinate system for a specific Gausspoint. @@ -78,28 +80,38 @@ namespace Mat * \return const CylinderCoordinateSystemProvider& Reference to the cylinder coordinate system * provider */ - const CylinderCoordinateSystemProvider& get_cylinder_coordinate_system(int gp) const; + [[nodiscard]] const CylinderCoordinateSystemProvider& get_cylinder_coordinate_system( + int gp) const; - std::shared_ptr get_coordinate_system_provider(int gp) const; + [[nodiscard]] std::shared_ptr get_coordinate_system_provider( + int gp) const; private: /*! * \brief This method will be called by Mat::Anisotropy to notify that element information is * available. */ - void on_global_element_data_initialized() override; + void on_global_element_data_initialized(Anisotropy& anisotropy) override; /*! * \brief This method will be called by Mat::Anisotropy to notify that Gauss point information * is available. */ - void on_global_gp_data_initialized() override; + void on_global_gp_data_initialized(Anisotropy& anisotropy) override; /// flag where the coordinate system is located CosyLocation cosy_location_; + + /// element-level cylinder coordinate system manager supplied by the Anisotropy class during + /// setup + std::optional element_cosy_; + + /// Gauss-point-level cylinder coordinate system managers supplied by the Anisotropy class + /// during setup + std::vector gp_cosy_; }; } // namespace Mat FOUR_C_NAMESPACE_CLOSE -#endif \ No newline at end of file +#endif diff --git a/src/mat/4C_mat_anisotropy_extension_default.cpp b/src/mat/4C_mat_anisotropy_extension_default.cpp index 9a8425d7fe5..b0822d5afd0 100644 --- a/src/mat/4C_mat_anisotropy_extension_default.cpp +++ b/src/mat/4C_mat_anisotropy_extension_default.cpp @@ -146,7 +146,8 @@ void Mat::DefaultAnisotropyExtension::set_fiber_vecs( } template -bool Mat::DefaultAnisotropyExtension::do_element_fiber_initialization() +bool Mat::DefaultAnisotropyExtension::do_element_fiber_initialization( + Mat::Anisotropy& anisotropy) { switch (init_mode_) { @@ -156,25 +157,24 @@ bool Mat::DefaultAnisotropyExtension::do_element_fiber_initialization() case INIT_MODE_ELEMENT_FIBERS: // check, whether a coordinate system is given - if (this->get_anisotropy()->has_element_cylinder_coordinate_system()) + if (anisotropy.has_element_cylinder_coordinate_system()) { // initialize fiber vector with local coordinate system Core::LinAlg::Tensor locsys{}; const Core::LinAlg::Tensor Id = Core::LinAlg::get_full(Core::LinAlg::TensorGenerators::identity); - this->get_anisotropy() - ->get_element_cylinder_coordinate_system() - .evaluate_local_coordinate_system(locsys); + anisotropy.get_element_cylinder_coordinate_system().evaluate_local_coordinate_system( + locsys); this->set_fiber_vecs(-1.0, locsys, Id); } - else if (this->get_anisotropy()->get_number_of_element_fibers() > 0) + else if (anisotropy.get_number_of_element_fibers() > 0) { // initialize fibers from global given fibers std::array, numfib> fibers; for (unsigned int i = 0; i < numfib; ++i) { - fibers[i] = this->get_anisotropy()->get_element_fibers().at(fiber_ids_.at(i)); + fibers[i] = anisotropy.get_element_fibers().at(fiber_ids_.at(i)); } this->set_fibers(BaseAnisotropyExtension::GPDEFAULT, fibers); } @@ -190,7 +190,8 @@ bool Mat::DefaultAnisotropyExtension::do_element_fiber_initialization() } template -bool Mat::DefaultAnisotropyExtension::do_gp_fiber_initialization() +bool Mat::DefaultAnisotropyExtension::do_gp_fiber_initialization( + Mat::Anisotropy& anisotropy) { switch (init_mode_) { @@ -200,17 +201,17 @@ bool Mat::DefaultAnisotropyExtension::do_gp_fiber_initialization() case INIT_MODE_NODAL_FIBERS: // check, whether a coordinate system is given - if (this->get_anisotropy()->has_gp_cylinder_coordinate_system()) + if (anisotropy.has_gp_cylinder_coordinate_system()) { FOUR_C_THROW( "Gauss-point fibers defined via Gauss-point cylinder coordinate systems is not yet " "defined"); } - else if (this->get_anisotropy()->get_number_of_gauss_point_fibers() > 0) + else if (anisotropy.get_number_of_gauss_point_fibers() > 0) { // initialize fibers from global given fibers int gp = 0; - for (const auto& fiberList : this->get_anisotropy()->get_gauss_point_fibers()) + for (const auto& fiberList : anisotropy.get_gauss_point_fibers()) { std::array, numfib> fibers; diff --git a/src/mat/4C_mat_anisotropy_extension_default.hpp b/src/mat/4C_mat_anisotropy_extension_default.hpp index 423552aad00..de75e58b97f 100644 --- a/src/mat/4C_mat_anisotropy_extension_default.hpp +++ b/src/mat/4C_mat_anisotropy_extension_default.hpp @@ -74,7 +74,7 @@ namespace Mat * \return true if the material is parametrized so that element fibers should be used * \return false otherwise */ - bool do_element_fiber_initialization() override; + bool do_element_fiber_initialization(Anisotropy& anisotropy) override; /*! * \brief Initializes Gauss point fibers @@ -82,7 +82,7 @@ namespace Mat * \return true if the materials is parametrized so that Gauss point fibers should be used * \return false otherwise */ - bool do_gp_fiber_initialization() override; + bool do_gp_fiber_initialization(Anisotropy& anisotropy) override; /*! * \brief Set Fiber vectors by a new angle gamma in the current configuration diff --git a/src/mat/4C_mat_elasthyper.cpp b/src/mat/4C_mat_elasthyper.cpp index 288c103a009..63f6e0560f5 100644 --- a/src/mat/4C_mat_elasthyper.cpp +++ b/src/mat/4C_mat_elasthyper.cpp @@ -78,14 +78,12 @@ Mat::ElastHyper::ElastHyper(Mat::PAR::ElastHyper* params) : summandProperties_(), params_(params), potsum_(0), anisotropy_() { // make sure the referenced materials in material list have quick access parameters - std::vector::const_iterator m; - for (m = params_->matids_.begin(); m != params_->matids_.end(); ++m) + for (const int matid : params_->matids_) { - const int matid = *m; - std::shared_ptr sum = Mat::Elastic::Summand::factory(matid); - if (sum == nullptr) FOUR_C_THROW("Failed to allocate"); - potsum_.push_back(sum); + auto sum = Mat::Elastic::Summand::factory(matid); + if (!sum) FOUR_C_THROW("Failed to allocate material summand for matid {}", matid); sum->register_anisotropy_extensions(anisotropy_); + potsum_.push_back(std::move(sum)); } } @@ -150,7 +148,6 @@ void Mat::ElastHyper::unpack(Core::Communication::UnpackBuffer& buffer) summandProperties_.unpack(buffer); - // Pack anisotropy anisotropy_.unpack_anisotropy(buffer); Core::Communication::PotentiallyUnusedBufferScope potsum_scope(buffer); @@ -158,13 +155,13 @@ void Mat::ElastHyper::unpack(Core::Communication::UnpackBuffer& buffer) if (params_ != nullptr) // summands are not accessible in postprocessing mode { // make sure the referenced materials in material list have quick access parameters - std::vector::const_iterator m; - for (m = params_->matids_.begin(); m != params_->matids_.end(); ++m) + for (const int matid : params_->matids_) { - const int summand_matid = *m; - std::shared_ptr sum = Mat::Elastic::Summand::factory(summand_matid); - if (sum == nullptr) FOUR_C_THROW("Failed to allocate"); - potsum_.push_back(sum); + auto sum = Mat::Elastic::Summand::factory(matid); + + if (!sum) FOUR_C_THROW("Failed to allocate Elastic::Summand for matid {}", matid); + + potsum_.push_back(std::move(sum)); } // loop map of associated potential summands @@ -209,32 +206,6 @@ double Mat::ElastHyper::shear_mod(int ele_gid) const return shearmod; } -/*----------------------------------------------------------------------*/ -/*----------------------------------------------------------------------*/ -double Mat::ElastHyper::get_young() -{ - double young; - double shear; - double bulk; - young = shear = bulk = 0.; - for (auto& p : potsum_) p->add_youngs_mod(young, shear, bulk); - - if (bulk != 0. || shear != 0.) young += 9. * bulk * shear / (3. * bulk + shear); - - return young; -} - -/*----------------------------------------------------------------------*/ -/*----------------------------------------------------------------------*/ -void Mat::ElastHyper::setup_aaa(const Teuchos::ParameterList& params, const int eleGID) -{ - // loop map of associated potential summands - for (auto& p : potsum_) - { - p->setup_aaa(params, eleGID); - } -} - /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ void Mat::ElastHyper::setup(int numgp, const Discret::Elements::Fibers& fibers, diff --git a/src/mat/4C_mat_elasthyper.hpp b/src/mat/4C_mat_elasthyper.hpp index 33c499a60f7..fefa492be6f 100644 --- a/src/mat/4C_mat_elasthyper.hpp +++ b/src/mat/4C_mat_elasthyper.hpp @@ -53,12 +53,6 @@ namespace Mat /// @name material parameters //@{ - - // /// provide access to material/summand by its ID - // std::shared_ptr MaterialById( - // const int id ///< ID to look for in collection of summands - // ) const; - /// length of material list const int nummat_; @@ -192,7 +186,7 @@ namespace Mat } /// number of materials - virtual int num_mat() const { return params_->nummat_; } + [[nodiscard]] virtual int num_mat() const { return params_->nummat_; } /*! * @brief deliver material ID of index i'th potential summand in collection @@ -200,16 +194,13 @@ namespace Mat * @param(in) index index * @return material id */ - virtual int mat_id(unsigned index) const; + [[nodiscard]] virtual int mat_id(unsigned index) const; /// material mass density - double density() const override { return params_->density_; } + [[nodiscard]] double density() const override { return params_->density_; } /// a shear modulus equivalent - virtual double shear_mod(int ele_gid) const; - - /// a young's modulus equivalent - virtual double get_young(); + [[nodiscard]] virtual double shear_mod(int ele_gid) const; /// evaluate strain energy function [[nodiscard]] double strain_energy(const Core::LinAlg::SymmetricTensor& glstrain, @@ -311,9 +302,6 @@ namespace Mat /// update void update() override; - /// setup patient-specific AAA stuff - virtual void setup_aaa(const Teuchos::ParameterList& params, int eleGID); - /// return if anisotropic not split formulation virtual bool anisotropic_principal() const { return summandProperties_.anisoprinc; } diff --git a/src/mat/4C_mat_elasthyper_service.cpp b/src/mat/4C_mat_elasthyper_service.cpp index 12282f8bb9c..65a3d84b11a 100644 --- a/src/mat/4C_mat_elasthyper_service.cpp +++ b/src/mat/4C_mat_elasthyper_service.cpp @@ -12,6 +12,7 @@ #include "4C_linalg_fixedsizematrix_voigt_notation.hpp" #include "4C_linalg_symmetric_tensor_eigen.hpp" #include "4C_linalg_tensor_conversion.hpp" +#include "4C_linalg_tensor_einstein.hpp" #include "4C_linalg_tensor_generators.hpp" #include "4C_linalg_utils_densematrix_eigen.hpp" #include "4C_linalg_vector.hpp" @@ -577,32 +578,24 @@ void Mat::elast_hyper_check_polyconvexity(const Core::LinAlg::Tensor& iFinM, - const Core::LinAlg::SymmetricTensor& CM, Core::LinAlg::Matrix<6, 6>& dCedC, - Core::LinAlg::Matrix<6, 9>& dCediFin) + const Core::LinAlg::SymmetricTensor& CM, + Core::LinAlg::SymmetricTensor& dCedC, + Core::LinAlg::Tensor& dCediFin) { - Core::LinAlg::Matrix<3, 3> iFinM_mat = Core::LinAlg::make_matrix_view(iFinM); - const Core::LinAlg::Matrix<3, 3> C_mat = Core::LinAlg::make_matrix(Core::LinAlg::get_full(CM)); - // auxiliaries - Core::LinAlg::Matrix<3, 3> id3x3(Core::LinAlg::Initialization::zero); - for (int i = 0; i < 3; ++i) id3x3(i, i) = 1.0; - Core::LinAlg::Matrix<9, 9> temp9x9(Core::LinAlg::Initialization::zero); - Core::LinAlg::FourTensor<3> tempFourTensor(true); + // F_in^{-T} and the 2nd order identity tensor + const Core::LinAlg::Tensor iFinT = Core::LinAlg::transpose(iFinM); + const Core::LinAlg::SymmetricTensor id = + Core::LinAlg::TensorGenerators::identity; // \frac{\partial C^e}{\partial C} - dCedC.clear(); - Core::LinAlg::Matrix<3, 3> iFinTM(Core::LinAlg::Initialization::zero); - iFinTM.multiply_nt(1.0, id3x3, iFinM_mat, 0.0); - Core::LinAlg::FourTensorOperations::add_kronecker_tensor_product(dCedC, 1.0, iFinTM, iFinTM, 0.0); + dCedC = Core::LinAlg::assume_symmetry(0.5 * (Core::LinAlg::einsum<"ik", "jl">(iFinT, iFinT) + + Core::LinAlg::einsum<"il", "jk">(iFinT, iFinT))); + + const Core::LinAlg::Tensor iFinTC = Core::LinAlg::dot(iFinT, CM); // \frac{\partial C^e}{\partial F_{in}^{-1}} - dCediFin.clear(); - Core::LinAlg::Matrix<3, 3> iFinTCM(Core::LinAlg::Initialization::zero); - iFinTCM.multiply_tn(1.0, iFinM_mat, C_mat, 0.0); - temp9x9.clear(); - Core::LinAlg::FourTensorOperations::add_adbc_tensor_product(1.0, id3x3, iFinTCM, temp9x9); - Core::LinAlg::FourTensorOperations::add_non_symmetric_product(1.0, iFinTCM, id3x3, temp9x9); - Core::LinAlg::Voigt::setup_four_tensor_from_9x9_voigt_matrix(tempFourTensor, temp9x9); - Core::LinAlg::Voigt::setup_6x9_voigt_matrix_from_four_tensor(dCediFin, tempFourTensor); + dCediFin = + Core::LinAlg::einsum<"ad", "bc">(id, iFinTC) + Core::LinAlg::einsum<"ac", "bd">(iFinTC, id); } FOUR_C_NAMESPACE_CLOSE diff --git a/src/mat/4C_mat_elasthyper_service.hpp b/src/mat/4C_mat_elasthyper_service.hpp index d5b48592d27..879c8487458 100644 --- a/src/mat/4C_mat_elasthyper_service.hpp +++ b/src/mat/4C_mat_elasthyper_service.hpp @@ -379,15 +379,16 @@ namespace Mat * @param[in] iFinM Inverse inelastic deformation gradient * @param[in] CM Right Cauchy-Green deformation tensor * @param[out] dCedC Partial derivative of the elastic right CG tensor w.r.t. right CG - * tensor (Voigt stress-stress notation) + * tensor (symmetric 4th order tensor) * @param[out] dCediFin Partial derivative of the elastic right CG tensor w.r.t. inelastic - * deformation gradient (Voigt stress notation) + * deformation gradient (full 4th order tensor) * */ void elast_hyper_get_derivs_of_elastic_right_cg_tensor( const Core::LinAlg::Tensor& iFinM, - const Core::LinAlg::SymmetricTensor& CM, Core::LinAlg::Matrix<6, 6>& dCedC, - Core::LinAlg::Matrix<6, 9>& dCediFin); + const Core::LinAlg::SymmetricTensor& CM, + Core::LinAlg::SymmetricTensor& dCedC, + Core::LinAlg::Tensor& dCediFin); /** * \brief Class for holding the summand formulation properties diff --git a/src/mat/4C_mat_inelastic_defgrad_factors.cpp b/src/mat/4C_mat_inelastic_defgrad_factors.cpp index b7904dd8445..cb1e34ebdec 100644 --- a/src/mat/4C_mat_inelastic_defgrad_factors.cpp +++ b/src/mat/4C_mat_inelastic_defgrad_factors.cpp @@ -8,6 +8,7 @@ #include "4C_mat_inelastic_defgrad_factors.hpp" #include "4C_comm_mpi_utils.hpp" +#include "4C_comm_pack_helpers.hpp" #include "4C_fem_discretization.hpp" #include "4C_global_data.hpp" #include "4C_legacy_enum_definitions_materials.hpp" @@ -475,26 +476,6 @@ namespace Core::LinAlg::EigenvalInterpolationType::LOG, interp_param_list}; } - Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonParams - retrieve_local_newton_params(const Core::Mat::PAR::Parameter::Data& matdata) - { - const auto local_newton_params = ViscoplastUtils::LocalNewtonParams{ - .res_tol = matdata.parameters.group("LOCAL_NEWTON").get("RES_TOL"), - .incr_tol = matdata.parameters.group("LOCAL_NEWTON").get("INCR_TOL"), - .conv_check = matdata.parameters.group("LOCAL_NEWTON") - .get("CONV_CHECK"), - .diver_cont = matdata.parameters.group("LOCAL_NEWTON") - .get("DIVER_CONT"), - .max_iter = static_cast( - matdata.parameters.group("LOCAL_NEWTON").get("MAX_ITER")), - .max_exceedance_fact_res_tol = - matdata.parameters.group("LOCAL_NEWTON").get("MAX_EXCEEDANCE_FACT_RES_TOL"), - .max_exceedance_fact_incr_tol = - matdata.parameters.group("LOCAL_NEWTON").get("MAX_EXCEEDANCE_FACT_INCR_TOL"), - }; - - return local_newton_params; - } bool show_warnings(const unsigned int ele_gid) { @@ -701,9 +682,6 @@ Mat::PAR::InelasticDefgradTransvIsotropElastViscoplast:: matdata.parameters.get("TIME_INTEGRATION_HIST_VARS")), linearization_type_( matdata.parameters.get("LINEARIZATION")), - max_plastic_strain_incr_(matdata.parameters.get("MAX_PLASTIC_STRAIN_INCR")), - max_plastic_strain_deriv_incr_( - matdata.parameters.get("MAX_PLASTIC_STRAIN_DERIV_INCR")), use_local_substepping_( matdata.parameters.group("LOCAL_SUBSTEPPING").get("USE_SUBSTEPPING")), max_local_substepping_halve_num_(static_cast( @@ -718,7 +696,11 @@ Mat::PAR::InelasticDefgradTransvIsotropElastViscoplast:: mat_log_deriv_calc_method_( matdata.parameters.get( "MATRIX_LOG_DERIV_CALC_METHOD")), - local_newton_params_(retrieve_local_newton_params(matdata)) + local_newton_params_( + matdata.parameters.get("LOCAL_NEWTON")), + error_registration_settings_( + matdata.parameters.get( + "ERROR_REGISTRATION_SETTINGS")) { // consistency check: yield parameters in case of transversely-isotropic behavior const bool all_yield_cond_param_specified = @@ -845,7 +827,8 @@ std::shared_ptr Mat::InelasticDefgradFactors::fact dynamic_cast(current_material); // create viscoplastic law - auto viscoplastic_law = Mat::Viscoplastic::Law::factory(params->viscoplastic_law_id()); + auto viscoplastic_law = Mat::Viscoplastic::Law::factory( + params->viscoplastic_law_id(), params->error_registration_settings()); // construct fiber reader auto* fiber_reader_params = Global::Problem::instance(probinst)->materials()->parameter_by_id( @@ -1814,6 +1797,9 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::InelasticDefgradTransvIsotrop // initialize time step quantities time_step_quantities_.init(ref_temperature_); + + // initialize vector tracking plastic flow for a single Gauss point; we resize it afterwards + is_plastic_gp_.resize(1, false); } @@ -1856,9 +1842,9 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::pre_evaluate( } // set time step - FOUR_C_ASSERT(context.time_step_size, "Time step size not given in evaluation context."); + FOUR_C_ASSERT_ALWAYS(context.time_step_size, "Time step size not given in evaluation context."); time_step_tracker_.dt = *context.time_step_size; - FOUR_C_ASSERT(context.total_time, "Total time not given in evaluation context."); + FOUR_C_ASSERT_ALWAYS(context.total_time, "Total time not given in evaluation context."); time_step_tracker_.tnp = *context.total_time; // set minimum substep length @@ -1875,18 +1861,6 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::pre_evaluate( viscoplastic_law_->pre_evaluate(params, gp); } -/*--------------------------------------------------------------------* - *--------------------------------------------------------------------*/ -void Mat::InelasticDefgradTransvIsotropElastViscoplast::prepare_return_mapping() -{ - // pre-evaluate viscoplastic law - viscoplastic_law_->pre_evaluate(params_, gp_); - - // reset local iteration count - local_newton_manager_.set_iteration_count(0); -} - - /*--------------------------------------------------------------------* *--------------------------------------------------------------------*/ void Mat::InelasticDefgradTransvIsotropElastViscoplast::calculate_gamma_delta( @@ -1926,6 +1900,8 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_state_quantities( ViscoplastUtils::ErrorType& err_status, const double dt, const ViscoplastUtils::StateQuantityEvalType& eval_type) const { + ensure_error_free_evaluation(err_status); + ViscoplastUtils::StateQuantities state_quantities{}; state_quantities.eval_type = eval_type; @@ -1974,25 +1950,8 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_state_quantities( Core::LinAlg::Matrix<3, 3> CeCeM(Core::LinAlg::Initialization::zero); CeCeM.multiply_nn(1.0, state_quantities.curr_CeM, state_quantities.curr_CeM, 0.0); - // thermal quantities and stress factors - Mat::ThermalQuantities thermal_quantities = - Mat::evaluate_thermal_quantities(temperature - ref_temperature_, - thermal_expansion_coefficient_, iFinM, gp_, ele_gid_, potsumel_); - Mat::StressFactors thermal_stress_factors; - Mat::calculate_gamma_delta(thermal_stress_factors.gamma, thermal_stress_factors.delta, - thermal_quantities.prinv, thermal_quantities.dPI, thermal_quantities.ddPII); - - // compute mixed thermo-elastic tensors required for reducing the Mandel stress based on - // temperature - Core::LinAlg::Matrix<3, 3> CT{Core::LinAlg::Initialization::zero}; - Core::LinAlg::Voigt::Stresses::vector_to_matrix(thermal_quantities.CTV, CT); - Core::LinAlg::Matrix<3, 3> iCT{Core::LinAlg::Initialization::zero}; - Core::LinAlg::Voigt::Stresses::vector_to_matrix(thermal_quantities.iCTV, iCT); - Core::LinAlg::Matrix<3, 3> CeCT{Core::LinAlg::Initialization::zero}; - CeCT.multiply_nn(1.0, state_quantities.curr_CeM, CT, 0.0); - Core::LinAlg::Matrix<3, 3> CeiCT{Core::LinAlg::Initialization::zero}; - CeiCT.multiply_nn(1.0, state_quantities.curr_CeM, iCT, 0.0); - + state_quantities.curr_ST = Mat::ThermalExpansion::compute_thermoelastic_stress_contribution( + temperature - ref_temperature_, thermal_expansion_coefficient_, potsumel_, gp_, ele_gid_); /** compute symmetric part of thermo-elastic Mandel stress tensor @@ -2003,9 +1962,9 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_state_quantities( Mtheta_sym_M.update(state_quantities.curr_gamma(0), state_quantities.curr_CeM, state_quantities.curr_gamma(1), CeCeM, 0.0); Mtheta_sym_M.update(state_quantities.curr_gamma(2), const_non_mat_tensors.id3x3, 1.0); - Mtheta_sym_M.update(-1.0 * thermal_stress_factors.gamma(0), state_quantities.curr_CeM, 1.0); - Mtheta_sym_M.update(-1.0 * thermal_stress_factors.gamma(1), CeCT, 1.0); - Mtheta_sym_M.update(-1.0 * thermal_stress_factors.gamma(2), CeiCT, 1.0); + const auto& CeS_T = + dot(make_tensor_view(state_quantities.curr_CeM), state_quantities.curr_ST.value); + Mtheta_sym_M.update(-1.0, make_matrix_view(CeS_T), 1.0); if (parameter()->mat_behavior() == ViscoplastUtils::MatBehavior::transv_isotropic) { Core::LinAlg::Matrix<3, 3> addMeM(Core::LinAlg::Initialization::zero); @@ -2031,8 +1990,8 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_state_quantities( // determine scalar quantities of invariants / pseudoinvariants needed to compute the // equivalent tensile stress double Mtheta_dev_sym_contract_Mtheta_dev_sym = - Core::LinAlg::FourTensorOperations::contract_matrix_matrix( - state_quantities.curr_Mtheta_dev_sym_M, state_quantities.curr_Mtheta_dev_sym_M); + Core::LinAlg::ddot(Core::LinAlg::make_tensor_view(state_quantities.curr_Mtheta_dev_sym_M), + Core::LinAlg::make_tensor_view(state_quantities.curr_Mtheta_dev_sym_M)); Core::LinAlg::Matrix<3, 3> Mtheta_dev_sym_squared_M(Core::LinAlg::Initialization::zero); Mtheta_dev_sym_squared_M.multiply_nn( 1.0, state_quantities.curr_Mtheta_dev_sym_M, state_quantities.curr_Mtheta_dev_sym_M, 0.0); @@ -2078,9 +2037,8 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_state_quantities( // calculate equivalent plastic strain rate using the viscoplastic law - state_quantities.curr_equiv_plastic_strain_rate = - viscoplastic_law_->evaluate_plastic_strain_rate(state_quantities.curr_equiv_stress, - plastic_strain, dt, parameter()->max_plastic_strain_incr(), err_status, update_hist_var_); + state_quantities.curr_equiv_plastic_strain_rate = viscoplastic_law_->evaluate_plastic_strain_rate( + state_quantities.curr_equiv_stress, plastic_strain, dt, err_status, update_hist_var_); if (eval_type == ViscoplastUtils::StateQuantityEvalType::plastic_strain_rate_only) { @@ -2200,6 +2158,9 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_state_quantity_deriv ViscoplastUtils::ErrorType& err_status, const double dt, const ViscoplastUtils::StateQuantityDerivEvalType& eval_type, const bool eval_state) const { + ensure_error_free_evaluation(err_status); + + ViscoplastUtils::StateQuantityDerivatives state_quantity_derivatives{}; state_quantity_derivatives.eval_type = eval_type; @@ -2233,12 +2194,18 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_state_quantity_deriv const Core::LinAlg::Matrix<3, 3> dpM = relevant_state_quantities.curr_dpM; const Core::LinAlg::Matrix<3, 3> lpM = relevant_state_quantities.curr_lpM; const Core::LinAlg::Matrix<3, 3> EpM = relevant_state_quantities.curr_EpM; + const TensorAndTemperatureDerivative ST = relevant_state_quantities.curr_ST; // compute the relevant derivatives of the elastic right Cauchy-Green deformation tensor + Core::LinAlg::SymmetricTensor dCedC_tensor; + Core::LinAlg::Tensor dCediFin_tensor; Mat::elast_hyper_get_derivs_of_elastic_right_cg_tensor(Core::LinAlg::make_tensor(iFinM), - Core::LinAlg::assume_symmetry(Core::LinAlg::make_tensor(CM)), - state_quantity_derivatives.curr_dCedC, state_quantity_derivatives.curr_dCediFin); + Core::LinAlg::assume_symmetry(Core::LinAlg::make_tensor(CM)), dCedC_tensor, dCediFin_tensor); + state_quantity_derivatives.curr_dCedC = + Core::LinAlg::make_6x6_voigt_matrix_from_tensor(dCedC_tensor); + state_quantity_derivatives.curr_dCediFin = + Core::LinAlg::make_6x9_voigt_matrix_from_tensor(dCediFin_tensor); // save these also as four tensors Core::LinAlg::FourTensor<3> dCediFin_FourTensor(true); Core::LinAlg::Voigt::setup_four_tensor_from_6x9_voigt_matrix( @@ -2309,19 +2276,7 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_state_quantity_deriv Core::LinAlg::Matrix<6, 1> iCV(Core::LinAlg::Initialization::zero); Core::LinAlg::Voigt::Stresses::matrix_to_vector(iCM, iCV); - // thermal quantities and stress factors - Mat::ThermalQuantities thermal_quantities = - Mat::evaluate_thermal_quantities(temperature - ref_temperature_, - thermal_expansion_coefficient_, iFinM, gp_, ele_gid_, potsumel_); - Core::LinAlg::SymmetricTensor hyperelast_stress_CT{}; - Core::LinAlg::SymmetricTensor hyperelast_stiffness_CT{}; - Mat::elast_hyper_add_isotropic_stress_cmat(hyperelast_stress_CT, hyperelast_stiffness_CT, - Core::LinAlg::make_symmetric_tensor_from_stress_like_voigt_matrix(thermal_quantities.CTV), - Core::LinAlg::make_symmetric_tensor_from_stress_like_voigt_matrix(thermal_quantities.iCTV), - thermal_quantities.prinv, thermal_quantities.dPI, thermal_quantities.ddPII); - const Core::LinAlg::Matrix<3, 3> S_T = - Core::LinAlg::make_matrix(Core::LinAlg::get_full(hyperelast_stress_CT)); - + const auto S_T = make_matrix(get_full(ST.value)); // compute the relevant derivatives of the symmetric part of the Mandel stress /** @@ -2391,11 +2346,7 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_state_quantity_deriv \f$ \frac{\partial \boldsymbol{M}_{\theta, \text{sym}} }{\partial T} = - \boldsymbol{C}_e \cdot \frac{\partial\boldsymbol{S}_{T}}{\partial T}\f$ (Voigt stress-form) */ - Core::LinAlg::Matrix<6, 1> dST_dT_V{Core::LinAlg::Initialization::zero}; - dST_dT_V.multiply_nn(0.5, Core::LinAlg::make_stress_like_voigt_view(hyperelast_stiffness_CT), - thermal_quantities.dCTdTV, 0.0); - Core::LinAlg::Matrix<3, 3> dST_dT_M{Core::LinAlg::Initialization::zero}; - Core::LinAlg::Voigt::Stresses::vector_to_matrix(dST_dT_V, dST_dT_M); + const auto dST_dT_M = make_matrix(get_full(ST.temperature_derivative)); Core::LinAlg::Matrix<3, 3> dMtheta_sym_dT_M(Core::LinAlg::Initialization::zero); dMtheta_sym_dT_M.multiply_nn(-1.0, CeM, dST_dT_M, 0.0); Core::LinAlg::Matrix<6, 1> dMtheta_sym_dT_V(Core::LinAlg::Initialization::zero); @@ -2554,8 +2505,8 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_state_quantity_deriv // compute the relevant derivatives of the plastic strain rate InelasticDefgradTransvIsotropElastViscoplastUtils::PlasticStrainRateDerivs evoEqFunctionDers = - viscoplastic_law_->evaluate_derivatives_of_plastic_strain_rate(equiv_stress, plastic_strain, - dt, parameter()->max_plastic_strain_deriv_incr(), err_status); + viscoplastic_law_->evaluate_derivatives_of_plastic_strain_rate( + equiv_stress, plastic_strain, dt, err_status); // return if we get an error, all other calculations are useless since substepping is // triggered @@ -2726,6 +2677,9 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_additional_cmat { const ReducedKinematics reduced_kinematics = evaluate_reduced_kinematics(*defgrad, iFin_other); const double temperature = time_step_quantities_.current_temperature[gp_]; + // calculate linearization term only if we have plastic flow + if (!is_plastic_gp_[gp_]) return; + if (parameter()->linearization_type() == ViscoplastUtils::LinearizationType::perturbation_based) { @@ -2938,7 +2892,7 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_taylor_quinney_heat_ if (not is_current_state) { // recompute the current history variables for the incoming state. This also sets the new state. - return_mapping(reduced_kinematics.defgrad, temperature); + constitutive_update(reduced_kinematics.defgrad, temperature); } // evaluate the relevant linearizations, using cached values when available @@ -3008,7 +2962,7 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_inverse_inelast // temperature was set by pre_evaluate const double temperature = params_.isParameter("temperature") ? params_.get("temperature") : ref_temperature_; - iFinM = return_mapping(reduced_kinematics.defgrad, temperature).inv_plastic_defgrad; + iFinM = constitutive_update(reduced_kinematics.defgrad, temperature).inv_plastic_defgrad; } /*--------------------------------------------------------------------* @@ -3178,20 +3132,21 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_history_variables_wr } Mat::InelasticDefgradTransvIsotropElastViscoplast::HistoryVariables -Mat::InelasticDefgradTransvIsotropElastViscoplast::return_mapping( +Mat::InelasticDefgradTransvIsotropElastViscoplast::constitutive_update( const Core::LinAlg::Matrix<3, 3>& FredM, const double temperature) { - // declare output: history variables (after return mapping) + // declare output: history variables (after the constitutive update) HistoryVariables result; - // compute right CG tensor corresponding to the given deformation gradient - Core::LinAlg::Matrix<3, 3> CredM(Core::LinAlg::Initialization::zero); - CredM.multiply_tn(1.0, FredM, FredM, 0.0); + // construct struct containing deformation tensors used for local integration + ViscoplastUtils::LocalIntegrationDeformationTensors deftensors( + FredM, time_step_quantities_.last_plastic_defgrad_inverse[gp_]); // perform non-repeatable pre-evaluation tasks (non-repeatable: not // called in the redundant evaluate call, which is already handled -> direct return // without calling this function) - prepare_return_mapping(); + viscoplastic_law_->pre_evaluate(params_, gp_); + is_plastic_gp_[gp_] = false; // set predictor: assume purely elastic behavior in this time step Core::LinAlg::Matrix<3, 3> iFinM_pred(Core::LinAlg::Initialization::zero); @@ -3201,13 +3156,13 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::return_mapping( ViscoplastUtils::ErrorType err_status = ViscoplastUtils::ErrorType::no_errors; // set current defgrad and current right CG tensor - time_step_quantities_.current_defgrad[gp_] = FredM; - time_step_quantities_.current_rightCG[gp_] = CredM; + time_step_quantities_.current_defgrad[gp_] = deftensors.defgrad; + time_step_quantities_.current_rightCG[gp_] = deftensors.right_cg; time_step_quantities_.current_temperature[gp_] = temperature; thermo_mechanical_coupling_cache_.reset(gp_); // check whether the predictor is the solution (no plastic strain during this time step) - bool pred_is_sol = - check_elastic_predictor(CredM, temperature, iFinM_pred, plastic_strain_pred, err_status); + bool pred_is_sol = check_elastic_predictor( + deftensors.right_cg, temperature, iFinM_pred, plastic_strain_pred, err_status); if ((err_status == ViscoplastUtils::ErrorType::no_errors) && (pred_is_sol)) { // update inverse inelastic defgrad and plastic strain @@ -3216,19 +3171,19 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::return_mapping( } else // predictor does not suffice { + is_plastic_gp_[gp_] = true; + err_status = ViscoplastUtils::ErrorType::no_errors; // perform local time integration - Core::LinAlg::Matrix<10, 1> x = wrap_unknowns(iFinM_pred, plastic_strain_pred); - Core::LinAlg::Matrix<10, 1> sol = viscoplastic_correction(FredM, temperature, x, err_status); + Core::LinAlg::Matrix<10, 1> sol = viscoplastic_correction(deftensors, temperature, err_status); // throw error if the Local Newton Loop cannot be evaluated with the given substepping // settings if (err_status != ViscoplastUtils::ErrorType::no_errors) { // output error and then throw (in order to display the error on // the right processor) - const std::string extended_message = - get_error_info(Mat::InelasticDefgradTransvIsotropElastViscoplastUtils:: - get_detailed_error_message_for_error_type(err_status)); - FOUR_C_THROW("{}", extended_message); + FOUR_C_THROW("{}", get_error_warning_info(std::format( + "Viscoplastic correction was not successful! Error status: {}", + EnumTools::enum_name(err_status)))); } // update inverse inelastic defgrad and plastic strain @@ -3242,8 +3197,8 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::return_mapping( time_step_quantities_.current_plastic_defgrad_inverse[gp_] = result.inv_plastic_defgrad; time_step_quantities_.current_plastic_strain[gp_] = result.plastic_strain; time_step_quantities_.current_equiv_stress[gp_] = state_quantities_.curr_equiv_stress; - time_step_quantities_.current_rightCG[gp_] = CredM; - time_step_quantities_.current_defgrad[gp_] = FredM; + time_step_quantities_.current_rightCG[gp_] = deftensors.right_cg; + time_step_quantities_.current_defgrad[gp_] = deftensors.defgrad; } return result; @@ -3254,12 +3209,18 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::return_mapping( *--------------------------------------------------------------------*/ void Mat::InelasticDefgradTransvIsotropElastViscoplast::update() { - // update history variables for the next time step - time_step_quantities_.update(); - // call update method of the viscoplastic law - viscoplastic_law_->update(); - // reset Local Newton-Raphson manager - local_newton_manager_.reset(); + for (unsigned int gp = 0; gp < num_gp_; ++gp) + { + // update history variables for the next time step + time_step_quantities_.update(gp); + // reset saved number of iterations at each Gauss point within Local Newton-Raphson manager + local_newton_manager_.reset_curr_num_iters(gp); + if (is_plastic_gp_[gp]) + { + // call update method of the viscoplastic law + viscoplastic_law_->update(gp); + } + } } @@ -3272,6 +3233,9 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::setup(const int numgp, // auxiliaries Core::LinAlg::Matrix<6, 1> temp_6x1(Core::LinAlg::Initialization::zero); + // set number of Gauss points + num_gp_ = numgp; + // resize time step quantities according to the number of Gauss points time_step_quantities_.resize(numgp); thermo_mechanical_coupling_cache_.resize(numgp); @@ -3283,6 +3247,9 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::setup(const int numgp, // of Gauss points local_newton_manager_.resize(numgp); + // resize plastic flow tracking vector with the correct number of Gauss points + is_plastic_gp_.resize(numgp, is_plastic_gp_[0]); + // read fiber and structural tensor in the case of transverse isotropy if (parameter()->mat_behavior() == ViscoplastUtils::MatBehavior::transv_isotropic) { @@ -3294,7 +3261,7 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::setup(const int numgp, } else { - m_.scale(0.0); + m_.clear(); } // set material dependent constant tensors const_mat_tensors_.set_material_const_tensors(m_); @@ -3320,6 +3287,9 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::pack_inelastic( // pack Local Newton manager local_newton_manager_.pack(data); + + // pack plastic flow tracking vector + add_to_pack(data, is_plastic_gp_); } } @@ -3342,8 +3312,13 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::unpack_inelastic( time_step_quantities_.unpack(buffer); // unpack the Local Newton manager local_newton_manager_.unpack(buffer); + // unpack the plastic flow tracking vector + extract_from_pack(buffer, is_plastic_gp_); } + // set number of Gauss points manually, since the setup method is not called + num_gp_ = time_step_quantities_.last_defgrad.size(); + // now that the fiber direction is available, we set the material-dependent constant tensors // with it const_mat_tensors_.set_material_const_tensors(m_); @@ -3363,6 +3338,8 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_local_newton_residua const Core::LinAlg::Matrix<3, 3>& last_iFinM, const double dt, ViscoplastUtils::ErrorType& err_status) { + ensure_error_free_evaluation(err_status); + // auxiliaries Core::LinAlg::Matrix<3, 3> temp3x3(Core::LinAlg::Initialization::zero); @@ -3461,6 +3438,9 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_local_newton_jacobia const Core::LinAlg::Matrix<3, 3>& last_iFinM, const double dt, ViscoplastUtils::ErrorType& err_status) { + ensure_error_free_evaluation(err_status); + + // auxiliaries Core::LinAlg::FourTensor<3> tempFourTensor(true); Core::LinAlg::Matrix<9, 9> temp9x9(Core::LinAlg::Initialization::zero); @@ -3595,18 +3575,19 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_local_newton_jacobia *--------------------------------------------------------------------*/ Core::LinAlg::Matrix<10, 1> Mat::InelasticDefgradTransvIsotropElastViscoplast::viscoplastic_correction( - const Core::LinAlg::Matrix<3, 3>& defgrad, const double temperature, - const Core::LinAlg::Matrix<10, 1>& x, ViscoplastUtils::ErrorType& err_status) + const InelasticDefgradTransvIsotropElastViscoplastUtils::LocalIntegrationDeformationTensors& + deftensors, + const double temperature, ViscoplastUtils::ErrorType& err_status) { - // calculate right Cauchy-Green deformation tensor - Core::LinAlg::Matrix<3, 3> CM(Core::LinAlg::Initialization::zero); - CM.multiply_tn(1.0, defgrad, defgrad, 0.0); + ensure_error_free_evaluation(err_status); - // define solution vector - Core::LinAlg::Matrix<10, 1> sol = x; - // declare current right CG (tensor interpolated later on in each substep) - Core::LinAlg::Matrix<3, 3> curr_CM(Core::LinAlg::Initialization::zero); + // declare solution vector + Core::LinAlg::Matrix<10, 1> sol{Core::LinAlg::Initialization::zero}; + + // declare current defgrad (tensor interpolated later on in each substep) and right CG + Core::LinAlg::Matrix<3, 3> curr_FM{Core::LinAlg::Initialization::zero}; + // declare current temperature (interpolated later on in each substep) double curr_temp = 0.0; @@ -3625,23 +3606,30 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::viscoplastic_correction( { while (!local_substepping_utils_.end_substepping()) { - // interpolate right Cauchy-Green tensor if we use local substepping - curr_CM = tensor_interpolator_.get_interpolated_matrix( - {time_step_quantities_.last_rightCG[gp_], CM}, {0.0, 1.0}, + // interpolate deformation gradient if we use local substepping, and calculate the right + // Cauchy-Green deformation tensor accordingly + curr_FM = tensor_interpolator_.get_interpolated_matrix( + {time_step_quantities_.last_defgrad[gp_], deftensors.defgrad}, {0.0, 1.0}, local_substepping_utils_.get_normalized_next_time_param(time_step_tracker_.dt), tensor_interp_err_status); - FOUR_C_ASSERT_ALWAYS( - tensor_interp_err_status == Core::LinAlg::TensorInterpolationErrorType::NoErrors, - "Tensor interpolation failed with err: {}", - Core::LinAlg::make_error_message(tensor_interp_err_status)); + if (tensor_interp_err_status != Core::LinAlg::TensorInterpolationErrorType::NoErrors) + { + FOUR_C_THROW( + "{}", get_error_warning_info(std::format("Tensor interpolation failed with err: {}", + Core::LinAlg::make_error_message(tensor_interp_err_status)))); + } + ViscoplastUtils::LocalIntegrationDeformationTensors curr_deftensors( + curr_FM, time_step_quantities_.last_substep_plastic_defgrad_inverse[gp_]); + // interpolate temperature curr_temp = std::lerp(time_step_quantities_.last_temperature[gp_], temperature, local_substepping_utils_.get_normalized_next_time_param(time_step_tracker_.dt)); // perform substep local Newton loop - local_newton_loop(curr_CM, curr_temp, time_step_quantities_.last_substep_plastic_strain[gp_], - time_step_quantities_.last_substep_plastic_defgrad_inverse[gp_], - local_substepping_utils_.get_substep_size(), sol, err_status); + err_status = ViscoplastUtils::ErrorType::no_errors; + sol = local_newton_loop(curr_deftensors, curr_temp, + time_step_quantities_.last_substep_plastic_strain[gp_], + local_substepping_utils_.get_substep_size(), err_status); // update Local Newton quantities local_newton_manager_.update_after_local_newton(gp_); @@ -3657,19 +3645,19 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::viscoplastic_correction( extract_inverse_inelastic_defgrad(sol); time_step_quantities_.last_substep_plastic_strain[gp_] = sol(9); // update last substep history variables of the viscoplastic flow rule - viscoplastic_law_->update_gp_state(gp_); + viscoplastic_law_->update_gp_state_after_substep(gp_); } else { // halve and prepare a new substep - bool halving_success = halve_and_prepare_new_substep(sol, CM); + bool halving_success = halve_and_prepare_new_substep(sol, curr_deftensors.right_cg); // if the halving number was exceeded --> return with error if (!halving_success) { - const std::string extended_message = - get_error_info(Mat::InelasticDefgradTransvIsotropElastViscoplastUtils:: - get_detailed_error_message_for_error_type(err_status)); - FOUR_C_THROW("{}", extended_message); + FOUR_C_THROW( + "{}", get_error_warning_info(std::format( + "Maximum halving number for substepping was reached! Error status: {}", + EnumTools::enum_name(err_status)))); } } } @@ -3678,9 +3666,15 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::viscoplastic_correction( else { // perform local Newton loop - local_newton_loop(CM, temperature, time_step_quantities_.last_plastic_strain[gp_], - time_step_quantities_.last_plastic_defgrad_inverse[gp_], time_step_tracker_.dt, sol, - err_status); + + sol = local_newton_loop(deftensors, temperature, time_step_quantities_.last_plastic_strain[gp_], + time_step_tracker_.dt, err_status); + if (err_status != ViscoplastUtils::ErrorType::no_errors) + { + FOUR_C_THROW("{}", get_error_warning_info(std::format( + "There was an error within the local Newton! Error status: {}", + EnumTools::enum_name(err_status)))); + } // update Local Newton quantities and reset iteration counter local_newton_manager_.update_after_local_newton(gp_); @@ -3693,15 +3687,18 @@ Mat::InelasticDefgradTransvIsotropElastViscoplast::viscoplastic_correction( /*--------------------------------------------------------------------* *--------------------------------------------------------------------*/ -void Mat::InelasticDefgradTransvIsotropElastViscoplast::local_newton_loop( - const Core::LinAlg::Matrix<3, 3>& CM, const double temperature, - const double last_plastic_strain, const Core::LinAlg::Matrix<3, 3>& last_iFinM, const double dt, - Core::LinAlg::Matrix<10, 1>& sol, +Core::LinAlg::Matrix<10, 1> Mat::InelasticDefgradTransvIsotropElastViscoplast::local_newton_loop( + const InelasticDefgradTransvIsotropElastViscoplastUtils::LocalIntegrationDeformationTensors& + deftensors, + const double temperature, const double last_plastic_strain, const double dt, InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status) { + ensure_error_free_evaluation(err_status); + // auxiliaries Core::LinAlg::Matrix<10, 1> temp10x1(Core::LinAlg::Initialization::zero); + // Jacobian matrix Core::LinAlg::Matrix<10, 10> jacMat(Core::LinAlg::Initialization::zero); // increment of the solution variables @@ -3709,16 +3706,31 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::local_newton_loop( // residual of both equations Core::LinAlg::Matrix<10, 1> residual(Core::LinAlg::Initialization::zero); - // initialize quantities checked for convergence - ViscoplastUtils::LocalNewtonConvQuantities conv_quantities{ - .residual_norm = 1.0, .increment_norm = 1.0}; - // initialize evaluation management action ViscoplastUtils::EvaluationAction eval_action{ ViscoplastUtils::EvaluationAction::continue_current_iteration}; - // reset Local Newton iteration count - local_newton_manager_.set_iteration_count(0); + // initialize local Newton + local_newton_manager_.reset_iter(); + temp10x1 = determine_local_newton_init_estimate(dt, deftensors, last_plastic_strain, err_status); + local_newton_manager_.save_init_estimate_and_reset_convergence_quantities(temp10x1); + // handle eventual error in the initial estimate determination + if (err_status != ViscoplastUtils::ErrorType::no_errors) + { + // for substepping, we exit with the set error status and retry the computation with a smaller + // substep (eventually) + if (parameter()->use_local_substepping()) + { + return Core::LinAlg::Matrix<10, 1>{Core::LinAlg::Initialization::zero}; + } + // without substepping, we throw directly + else + { + FOUR_C_THROW( + "{}", get_error_warning_info("Could not compute initial estimate for the local Newton!")); + } + } + // local Newton-Raphson loop while (true) @@ -3726,15 +3738,12 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::local_newton_loop( // set error status to no_errors err_status = ViscoplastUtils::ErrorType::no_errors; - // increment iteration counter - local_newton_manager_.increment_iteration_count(); - // evaluate residual - residual = evaluate_local_newton_residual( - CM, temperature, sol, last_plastic_strain, last_iFinM, dt, err_status); + residual = evaluate_local_newton_residual(deftensors.right_cg, temperature, + local_newton_manager_.sol(), last_plastic_strain, + deftensors.elastic_predictor_inverse_plastic_defgrad, dt, err_status); // error management after residual evaluation - temp10x1.update(1.0, sol, 0.0); manage_evaluation(err_status, eval_action); switch (eval_action) { @@ -3745,40 +3754,37 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::local_newton_loop( } case (ViscoplastUtils::EvaluationAction::continue_with_next_iteration): { - // recompute dx after conducting adjustments to solution vector - dx.update(1.0, sol, -1.0, temp10x1, 0.0); - // proceed with next iteration after performing adjustments due // to errors + local_newton_manager_.increment_iter(); continue; } case (ViscoplastUtils::EvaluationAction::exit_with_error): { // exit with the set error status - return; + return Core::LinAlg::Matrix<10, 1>{Core::LinAlg::Initialization::zero}; } default: { - FOUR_C_THROW("Invalid evaluation action {} for error status {} after residual evaluation", - EnumTools::enum_name(eval_action), EnumTools::enum_name(err_status)); + FOUR_C_THROW( + "{}", get_error_warning_info(std::format( + "Invalid evaluation action {} for error status {} after residual evaluation", + EnumTools::enum_name(eval_action), EnumTools::enum_name(err_status)))); } } - // if we continue, then the residual evaluation was successful - - // verify convergence - conv_quantities.residual_norm = residual.norm2(); - const bool is_converged = is_local_newton_converged(conv_quantities); + // if we continue, then the residual evaluation was successful; verify convergence next + local_newton_manager_.set_residual_norm(residual); // exit in case of convergence - if (is_converged) + if (local_newton_manager_.is_local_newton_converged()) { - return; + return local_newton_manager_.sol(); } - // check if maximum iteration is exceeded - if (local_newton_manager_.iter() > local_newton_manager_.params().max_iter) + // check if maximum iteration is reached + if (local_newton_manager_.is_max_iter_reached()) { // set non-convergence error err_status = @@ -3789,24 +3795,24 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::local_newton_loop( // for a smaller substep size; hence, we return with the set error status if (parameter()->use_local_substepping()) { - return; + return Core::LinAlg::Matrix<10, 1>{ + Core::LinAlg::Initialization::zero}; // exit with the set error status } // for one-step processes, we account for the set divergence continuation strategy else { - verify_local_newton_exit(conv_quantities, err_status); - return; + verify_local_newton_exit(err_status); + return local_newton_manager_.sol(); } } else { // check whether the Local Newton is 'stuck' - if (is_local_newton_stuck(conv_quantities)) + if (local_newton_manager_.is_local_newton_stuck()) { // error management routine after the 'stuck' verification err_status = InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType:: no_convergence_local_newton; - temp10x1.update(1.0, sol, 0.0); manage_evaluation(err_status, eval_action); switch (eval_action) { @@ -3817,34 +3823,36 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::local_newton_loop( } case (ViscoplastUtils::EvaluationAction::continue_with_next_iteration): { - // recompute dx after conducting adjustments to solution vector - dx.update(1.0, sol, -1.0, temp10x1, 0.0); - // proceed with next iteration after performing adjustments due // to errors + local_newton_manager_.increment_iter(); continue; } case (ViscoplastUtils::EvaluationAction::exit_with_error): { // exit with the set error status - return; + return Core::LinAlg::Matrix<10, 1>{Core::LinAlg::Initialization::zero}; } default: { - FOUR_C_THROW( - "Invalid evaluation action {} for error status {} after verification of stuck " - "Local Newton", - EnumTools::enum_name(eval_action), EnumTools::enum_name(err_status)); + FOUR_C_THROW("{}", + get_error_warning_info(std::format( + "Invalid evaluation action {} for error status {} after verification of stuck " + "Local Newton", + EnumTools::enum_name(eval_action), EnumTools::enum_name(err_status)))); } } } } // evaluate Jacobian - jacMat = evaluate_local_newton_jacobian( - CM, temperature, sol, last_plastic_strain, last_iFinM, dt, err_status); + jacMat = evaluate_local_newton_jacobian(deftensors.right_cg, temperature, + local_newton_manager_.sol(), last_plastic_strain, + deftensors.elastic_predictor_inverse_plastic_defgrad, dt, err_status); + // error management after Jacobian evaluation manage_evaluation(err_status, eval_action); + switch (eval_action) { case (ViscoplastUtils::EvaluationAction::continue_current_iteration): @@ -3856,17 +3864,20 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::local_newton_loop( { // proceed with next iteration after performing adjustments due // to errors + local_newton_manager_.increment_iter(); continue; } case (ViscoplastUtils::EvaluationAction::exit_with_error): { // exit with the set error status - return; + return Core::LinAlg::Matrix<10, 1>{Core::LinAlg::Initialization::zero}; } default: { - FOUR_C_THROW("Invalid evaluation action {} for error status {} after Jacobian evaluation", - EnumTools::enum_name(eval_action), EnumTools::enum_name(err_status)); + FOUR_C_THROW( + "{}", get_error_warning_info(std::format( + "Invalid evaluation action {} for error status {} after Jacobian evaluation", + EnumTools::enum_name(eval_action), EnumTools::enum_name(err_status)))); } } @@ -3889,97 +3900,36 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::local_newton_loop( { // proceed with next iteration after performing adjustments due // to errors + local_newton_manager_.increment_iter(); continue; } case (ViscoplastUtils::EvaluationAction::exit_with_error): { // exit with the set error status - return; + return Core::LinAlg::Matrix<10, 1>{Core::LinAlg::Initialization::zero}; } + default: { FOUR_C_THROW( - "Invalid evaluation action {} for error status {} after solving linear system", - EnumTools::enum_name(eval_action), EnumTools::enum_name(err_status)); + "{}", get_error_warning_info(std::format("Invalid evaluation action {} for error " + "status {} after solving linear system", + EnumTools::enum_name(eval_action), EnumTools::enum_name(err_status)))); } } } - // update solution vector and relative increment - sol.update(1.0, dx, 1.0); - const double sol_norm = sol.norm2(); - const double dx_norm = dx.norm2(); - FOUR_C_ASSERT_ALWAYS(sol_norm >= 1.0e-8, - "The solution vector in local iteration {} is nearly 0, with 2-norm: {}! Something went " - "wrong, since such mechanical states are not expected!", - local_newton_manager_.iter(), sol_norm); - conv_quantities.increment_norm = dx_norm / sol_norm; - } -} + // update solution vector, iteration counter and increment norm + local_newton_manager_.increment_solution_vector(dx); -/*--------------------------------------------------------------------* - *--------------------------------------------------------------------*/ -bool Mat::InelasticDefgradTransvIsotropElastViscoplast::is_local_newton_converged( - const InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvQuantities& - conv_quantities) -{ - // check for convergence - switch (local_newton_manager_.params().conv_check) - { - case InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvCheck::residual: - return (conv_quantities.residual_norm <= local_newton_manager_.params().res_tol); - break; - case InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvCheck::increment_ratio: - return (conv_quantities.increment_norm <= local_newton_manager_.params().incr_tol); - break; - case InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvCheck:: - residual_and_increment_ratio: - return (conv_quantities.residual_norm <= local_newton_manager_.params().res_tol && - conv_quantities.increment_norm <= local_newton_manager_.params().incr_tol); - break; - default: - FOUR_C_THROW("You should not be here (convergence checking of the Local Newton Loop)"); + local_newton_manager_.increment_iter(); } } -/*--------------------------------------------------------------------* - *--------------------------------------------------------------------*/ -bool Mat::InelasticDefgradTransvIsotropElastViscoplast::is_local_newton_stuck( - const ViscoplastUtils::LocalNewtonConvQuantities& conv_quantities) -{ - // check for "stuck" Local Newton, i.e., the increment does not change much but there is not a - // converged state (check only feasible after the first iteration, since dx must be available) - if ((local_newton_manager_.iter() > 1) && (conv_quantities.increment_norm < 1.0e-15)) - { - // only in the case that the residual is verified, we set an - // error status - switch (local_newton_manager_.params().conv_check) - { - case InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvCheck::residual: - case FourC::Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvCheck:: - residual_and_increment_ratio: - { - return (conv_quantities.residual_norm > local_newton_manager_.params().res_tol); - } - case ViscoplastUtils::LocalNewtonConvCheck::increment_ratio: - { - return false; - } - default: - FOUR_C_THROW( - "You should not be here with convergence check type {} (check: is Local Newton " - "stuck?)", - EnumTools::enum_name(local_newton_manager_.params().conv_check)); - } - } - - return false; -} /*--------------------------------------------------------------------* *--------------------------------------------------------------------*/ void Mat::InelasticDefgradTransvIsotropElastViscoplast::verify_local_newton_exit( - const ViscoplastUtils::LocalNewtonConvQuantities& conv_quantities, InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status) { switch (local_newton_manager_.params().diver_cont) @@ -3987,10 +3937,10 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::verify_local_newton_exit case FourC::Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonDiverCont::stop: { // throw error: there is no convergence - const std::string extended_message = - get_error_info(Mat::InelasticDefgradTransvIsotropElastViscoplastUtils:: - get_detailed_error_message_for_error_type(err_status)); - FOUR_C_THROW("{}", extended_message); + FOUR_C_THROW( + "{}", get_error_warning_info( + ViscoplastUtils::get_detailed_error_message_for_error_type(err_status))); + return; } case FourC::Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonDiverCont:: continue_sim: @@ -4003,8 +3953,9 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::verify_local_newton_exit std::cout << std::format( "WARNING: The Local Newton Loop for ele_gid = {}, gp = {} did not reach " "convergence after {} iterations: residual = {}, increment = {}\n", - ele_gid_, gp_, local_newton_manager_.iter(), conv_quantities.residual_norm, - conv_quantities.increment_norm); + ele_gid_, gp_, local_newton_manager_.iter(), + local_newton_manager_.convergence_quantities().residual_norm, + local_newton_manager_.convergence_quantities().increment_norm); } // safeguard check: is the current solution within the bounds posed by the @@ -4014,11 +3965,11 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::verify_local_newton_exit continue_sim_with_safeguard) { const bool residual_within_bounds = - conv_quantities.residual_norm < + local_newton_manager_.convergence_quantities().residual_norm < (local_newton_manager_.params().res_tol * local_newton_manager_.params().max_exceedance_fact_res_tol); const bool incr_ratio_within_bounds = - conv_quantities.increment_norm < + local_newton_manager_.convergence_quantities().increment_norm < (local_newton_manager_.params().incr_tol * local_newton_manager_.params().max_exceedance_fact_incr_tol); @@ -4027,41 +3978,63 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::verify_local_newton_exit case FourC::Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvCheck:: residual: { - FOUR_C_ASSERT_ALWAYS(residual_within_bounds, - "Residual {} exceeds the residual tolerance {} by more than the set " - "exceedance tolerance factor {}!", - conv_quantities.residual_norm, local_newton_manager_.params().res_tol, - local_newton_manager_.params().max_exceedance_fact_res_tol); + if (!residual_within_bounds) + { + FOUR_C_THROW( + "{}", get_error_warning_info(std::format( + "Residual {} exceeds the residual tolerance {} by more than the set " + "exceedance tolerance factor {}! Error status: {}", + local_newton_manager_.convergence_quantities().residual_norm, + local_newton_manager_.params().res_tol, + local_newton_manager_.params().max_exceedance_fact_res_tol, + EnumTools::enum_name(err_status)))); + } + break; } case FourC::Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvCheck:: increment_ratio: { - FOUR_C_ASSERT_ALWAYS(incr_ratio_within_bounds, - "Relative increment {} exceeds the increment tolerance {} by more " - "than the set exceedance tolerance factor {}!", - conv_quantities.increment_norm, local_newton_manager_.params().incr_tol, - local_newton_manager_.params().max_exceedance_fact_incr_tol); + if (!incr_ratio_within_bounds) + { + FOUR_C_THROW( + "{}", get_error_warning_info(std::format( + "Relative increment {} exceeds the increment tolerance {} by more " + "than the set exceedance tolerance factor {}! Error status: {}", + local_newton_manager_.convergence_quantities().increment_norm, + local_newton_manager_.params().incr_tol, + local_newton_manager_.params().max_exceedance_fact_incr_tol, + EnumTools::enum_name(err_status)))); + } break; } case FourC::Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvCheck:: residual_and_increment_ratio: { - FOUR_C_ASSERT_ALWAYS(residual_within_bounds && incr_ratio_within_bounds, - "Residual {} and relative increment {} exceed the tolerances {} and {} by " - "more than the set exceedance tolerance factors {} and {}!", - conv_quantities.residual_norm, conv_quantities.increment_norm, - local_newton_manager_.params().res_tol, local_newton_manager_.params().incr_tol, - local_newton_manager_.params().max_exceedance_fact_res_tol, - local_newton_manager_.params().max_exceedance_fact_incr_tol); + if ((!residual_within_bounds) || (!incr_ratio_within_bounds)) + { + FOUR_C_THROW("{}", + get_error_warning_info(std::format( + "Residual {} and relative increment {} exceed the tolerances {} and {} by " + "more than the set exceedance tolerance factors {} and {}! Error status: {}", + local_newton_manager_.convergence_quantities().residual_norm, + local_newton_manager_.convergence_quantities().increment_norm, + local_newton_manager_.params().res_tol, + local_newton_manager_.params().incr_tol, + local_newton_manager_.params().max_exceedance_fact_res_tol, + local_newton_manager_.params().max_exceedance_fact_incr_tol, + EnumTools::enum_name(err_status)))); + } break; } default: - FOUR_C_THROW("Invalid convergence check {} (verification of safe Local Newton exit)", - EnumTools::enum_name(local_newton_manager_.params().conv_check)); + FOUR_C_THROW( + "{}", get_error_warning_info(std::format( + "Invalid convergence check {} (verification of safe Local Newton exit)", + EnumTools::enum_name(local_newton_manager_.params().conv_check)))); } } @@ -4072,13 +4045,16 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::verify_local_newton_exit } default: FOUR_C_THROW( - "You should not be here (divergence management strategy for Local Newton " - "Loop)"); + "{}", get_error_warning_info( + "You should not be here (divergence management strategy for Local Newton " + "Loop)")); } // safeguard for the function: each path must either return of throw - FOUR_C_THROW("The Local Newton scheme cannot be safely exited! Uncaught exception with error {}", - err_status); + FOUR_C_THROW( + "{}", get_error_warning_info(std::format( + "The Local Newton scheme cannot be safely exited! Uncaught exception with error {}", + EnumTools::enum_name(err_status)))); } /*--------------------------------------------------------------------* @@ -4087,7 +4063,8 @@ bool Mat::InelasticDefgradTransvIsotropElastViscoplast::solve_local_newton_linea const Core::LinAlg::Matrix<10, 1>& residual, const Core::LinAlg::Matrix<10, 10>& jacobian, Core::LinAlg::Matrix<10, 1>& dx) { - // auxiliaries: use copies of the residual and jacobian to avoid modifying the original variables + // auxiliaries: use copies of the residual and jacobian to avoid modifying the original + // variables Core::LinAlg::Matrix<10, 1> temp_negative_residual(Core::LinAlg::Initialization::zero); Core::LinAlg::Matrix<10, 10> temp_jacobian(Core::LinAlg::Initialization::zero); @@ -4113,12 +4090,14 @@ bool Mat::InelasticDefgradTransvIsotropElastViscoplast::check_elastic_predictor( const Core::LinAlg::Matrix<3, 3>& iFinM_pred, const double plastic_strain_pred, ViscoplastUtils::ErrorType& err_status) { + ensure_error_free_evaluation(err_status); + + // evaluate state with this elastic predictor and the minimum possible time step state_quantities_ = evaluate_state_quantities(CM, temperature, iFinM_pred, plastic_strain_pred, err_status, time_step_tracker_.min_dt, ViscoplastUtils::StateQuantityEvalType::plastic_strain_rate_only); - // check if the predicted plastic strain rate is 0 -> for flow rules with yield functions, // this means that the predictor is correct return (state_quantities_.curr_equiv_plastic_strain_rate * time_step_tracker_.dt <= @@ -4211,7 +4190,7 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_additional_cmat perturbed_CM.multiply_tn(1.0, perturbed_FM, perturbed_FM, 0.0); // get corresponding inverse inelastic defgrad - perturbed_iFinM = return_mapping(perturbed_FM, temperature).inv_plastic_defgrad; + perturbed_iFinM = constitutive_update(perturbed_FM, temperature).inv_plastic_defgrad; Core::LinAlg::Matrix<9, 1> perturbed_iFinV(Core::LinAlg::Initialization::zero); Core::LinAlg::Voigt::matrix_3x3_to_9x1(perturbed_iFinM, perturbed_iFinV); @@ -4265,7 +4244,7 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_od_stiff_mat_pe // run return-mapping with the perturbed temperature const HistoryVariables perturbed_history_variables = - return_mapping(FredM, perturbed_temperature); + constitutive_update(FredM, perturbed_temperature); Core::LinAlg::Matrix<9, 1> perturbed_iFinV(Core::LinAlg::Initialization::zero); Core::LinAlg::Voigt::matrix_3x3_to_9x1( @@ -4304,7 +4283,7 @@ Mat::HeatSource Mat::InelasticDefgradTransvIsotropElastViscoplast:: // Evaluate the incoming state params_.set("temperature", temperature); viscoplastic_law_->pre_evaluate(params_, gp_); - return_mapping(FredM, temperature); + constitutive_update(FredM, temperature); update_hist_var_ = false; // no update of the current values during perturbed evaluations const auto unperturbed_state_quantities = state_quantities_; @@ -4352,7 +4331,7 @@ Mat::HeatSource Mat::InelasticDefgradTransvIsotropElastViscoplast:: // run return-mapping with the perturbed deformation gradient. This populates the // state_quantities_ - return_mapping(perturbed_FM, temperature); + constitutive_update(perturbed_FM, temperature); result.derivative_wrt_cauchy_green(i) += delta_sign / (4.0 * pert_fact) * evaluate_taylor_quinney(state_quantities_); @@ -4375,7 +4354,7 @@ Mat::HeatSource Mat::InelasticDefgradTransvIsotropElastViscoplast:: viscoplastic_law_->pre_evaluate(params_, gp_); // run return-mapping with the perturbed temperature. This populates the state_quantities_ - return_mapping(FredM, perturbed_temperature); + constitutive_update(FredM, perturbed_temperature); result.derivative_wrt_temperature += delta_sign / (2 * delta_T_perturbation) * evaluate_taylor_quinney(state_quantities_); @@ -4418,22 +4397,22 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplast::manage_evaluation( eval_action = ViscoplastUtils::EvaluationAction::exit_with_error; return; } + // without evaluation management strategy, we can throw directly else { - FOUR_C_THROW( - "The Local Newton evaluation has failed with err status {} and there is no evaluation " - "management strategy " - "selected!", - err_status); + FOUR_C_THROW("{}", get_error_warning_info(std::format( + "The Local Newton evaluation has failed and there is no evaluation " + "management strategy " + "selected! Error status: {}", + EnumTools::enum_name(err_status)))); } } } - /*--------------------------------------------------------------------* *--------------------------------------------------------------------*/ -std::string Mat::InelasticDefgradTransvIsotropElastViscoplast::get_error_info( +std::string Mat::InelasticDefgradTransvIsotropElastViscoplast::get_error_warning_info( const std::string& base_error_string) const { // auxiliaries @@ -4444,7 +4423,11 @@ std::string Mat::InelasticDefgradTransvIsotropElastViscoplast::get_error_info( temp_ostream << std::fixed << std::setprecision(16) << std::endl; // declare the extended error message - std::string extended_error_string{local_substepping_utils_.get_info()}; + std::string extended_error_string{}; + if (parameter()->use_local_substepping()) + { + extended_error_string += local_substepping_utils_.get_info(); + } // get relevant error info extended_error_string += "BASE ERROR: \n"; @@ -4616,4 +4599,19 @@ bool Mat::InelasticDefgradTransvIsotropElastViscoplast::evaluate_output_data( return viscoplastic_law_->evaluate_output_data(name, data); } +/*--------------------------------------------------------------------* + *--------------------------------------------------------------------*/ +Core::LinAlg::Matrix<10, 1> +Mat::InelasticDefgradTransvIsotropElastViscoplast::determine_local_newton_init_estimate( + const double dt, + const InelasticDefgradTransvIsotropElastViscoplastUtils::LocalIntegrationDeformationTensors& + deftensors, + const double last_plastic_strain, + const InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status) const +{ + ensure_error_free_evaluation(err_status); + + // we use the elastic predictor + return wrap_unknowns(deftensors.elastic_predictor_inverse_plastic_defgrad, last_plastic_strain); +} FOUR_C_NAMESPACE_CLOSE diff --git a/src/mat/4C_mat_inelastic_defgrad_factors.hpp b/src/mat/4C_mat_inelastic_defgrad_factors.hpp index b68f6b10d90..b03151b9bcb 100644 --- a/src/mat/4C_mat_inelastic_defgrad_factors.hpp +++ b/src/mat/4C_mat_inelastic_defgrad_factors.hpp @@ -381,14 +381,6 @@ namespace Mat { return linearization_type_; } - //! get maximum, numerically evaluable plastic strain increment - [[nodiscard]] double max_plastic_strain_incr() const { return max_plastic_strain_incr_; } - //! get maximum, numerically evaluable value for the increment of - //! the plastic strain derivatives (dt * derivative) - [[nodiscard]] double max_plastic_strain_deriv_incr() const - { - return max_plastic_strain_deriv_incr_; - } //! get computation method for the matrix exponential [[nodiscard]] Core::LinAlg::MatrixExpCalcMethod mat_exp_calc_method() const { @@ -415,6 +407,12 @@ namespace Mat { return local_newton_params_; } + //! get error registration settings + [[nodiscard]] InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorRegistrationSettings + error_registration_settings() const + { + return error_registration_settings_; + } private: //! ID of the viscoplasticity law @@ -443,13 +441,6 @@ namespace Mat //! linearization method (analytic | perturbation based) InelasticDefgradTransvIsotropElastViscoplastUtils::LinearizationType linearization_type_; - //! maximum, numerically evaluable plastic strain increment - const double max_plastic_strain_incr_; - - //! maximum, numerically evaluable increment of - //! plastic strain derivatives (time_step * derivative) - const double max_plastic_strain_deriv_incr_; - //! use local substepping to integrate the viscoplastic evolution equations const bool use_local_substepping_; @@ -473,6 +464,10 @@ namespace Mat //! Local Newton--Raphson parameters const InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonParams local_newton_params_; + + //! get error registration settings for the constitutive update + const InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorRegistrationSettings + error_registration_settings_; }; } // namespace PAR @@ -1559,19 +1554,6 @@ namespace Mat void pre_evaluate(const Teuchos::ParameterList& params, const EvaluationContext<3>& context, int gp, int eleGID) override; - /*! - * Perform all preparation tasks for the return mapping in the current timestep. - * In contrast to the pre_evaluate method, these tasks shall not be repeated in case of the - * redundant evaluate call, see Issue #121 at https://github.com/4C-multiphysics/4C/issues/121. - * This means that the current, public pre-evaluate method performs only the safely repeatable - * pre-evaluation tasks. This also means that we prepare and perform the return mapping within - * evaluate_inverse_inelastic_defgrad only if we are not in the - * redundant call (see quick-fix PR #131 at - * https://github.com/4C-multiphysics/4C/pull/131). - * - */ - void prepare_return_mapping(); - void update() override; void pack_inelastic(Core::Communication::PackBuffer& data) const override; @@ -1644,10 +1626,13 @@ namespace Mat //! tensors associated with the director vector) InelasticDefgradTransvIsotropElastViscoplastUtils::ConstMatTensors const_mat_tensors_; - //! current Gauss Point - int gp_{-1}; + //! current Gauss point + unsigned int gp_{0}; + //! total number of Gauss points + unsigned int num_gp_{0}; + //! current element ID - int ele_gid_{-1}; + unsigned int ele_gid_{0}; //! parameter list Teuchos::ParameterList params_; @@ -1708,6 +1693,9 @@ namespace Mat //! dedicated Local Newton manager containing settings and iteration data InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonManager local_newton_manager_; + //! vector tracking whether there is plastic flow at each Gauss point + std::vector is_plastic_gp_; + /*! * @brief Calculate the Holzapfel gamma and delta values of the isotropic elastic material * components @@ -1764,28 +1752,6 @@ namespace Mat const double last_plastic_strain, const Core::LinAlg::Matrix<3, 3>& last_iFinM, const double dt, InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status); - - /*! - * @brief Determine whether the Local Newton Loop has converged. - * - * @param[in] conv_quantities quantities verified for convergence - * @return boolean: true = converged - */ - bool is_local_newton_converged( - const InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvQuantities& - conv_quantities); - - /*! - * @brief After an unsuccessful convergence check: determine whether the Local Newton is - * stuck, i.e., the relative solution increment is nearly 0, but there is no convergence yet. - * - * @param[in] conv_quantities quantities verified for convergence - * @return boolean: true = stuck - */ - bool is_local_newton_stuck( - const InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvQuantities& - conv_quantities); - /*! * @brief After an unsuccessful convergence check and after the maximum number of local * iterations has been exceeded: verifies whether the Local Newton scheme can be safely exited @@ -1794,15 +1760,11 @@ namespace Mat * @note If no error is thrown in this verification routine, then the Local Newton scheme can be * safely exited. The error status is reset to no_errors to continue with the computation. * - * @param[in] conv_quantities quantities verified for convergence * @param[in,out] err_status error status */ void verify_local_newton_exit( - const InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvQuantities& - conv_quantities, InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status); - /*! * @brief Solve local Newton linear system \f$ \boldsymbol{J} \mathrm{d}\boldsymbol{x} = - * \boldsymbol{r} \f$ to update the iteration vector @@ -1816,8 +1778,6 @@ namespace Mat bool solve_local_newton_linear_system(const Core::LinAlg::Matrix<10, 1>& residual, const Core::LinAlg::Matrix<10, 10>& jacobian, Core::LinAlg::Matrix<10, 1>& dx); - - /*! * @brief For a given right Cauchy_Green tensor and the Local NR Loop unknown vector, * compute the 10 x 10 Jacobian matrix required for the Local Newton Loop and the @@ -1849,22 +1809,22 @@ namespace Mat InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status); /*! - * @brief Performs the viscoplastic corrector step of the return mapping. + * @brief Performs the viscoplastic corrector step of the constitutive update. * * @note Uses local substepping if specified so by the user; the current time step is halved if * problematic numerical states, marked with an error status, are encountered * - * @param[in] defgrad deformation gradient \f$ \boldsymbol{F} \f$ in matrix form + * @param[in] deftensors deformation tensors used for local time integration (reset if + * substepping is used) * @param[in] temperature absolute temperature - * @param[in] x initial guess of Local Newton Loop, composed of the components of the - * inverse inelastic deformation gradient \f$ \boldsymbol{F}_{\text{in}}^{-1} \f$ - * and plastic strain \f$ \varepsilon_{\text{p}} \f$ * @param[out] err_status error status * @return solution vector of the Local Newton Loop, structured analogously to the initial guess * x */ - Core::LinAlg::Matrix<10, 1> viscoplastic_correction(const Core::LinAlg::Matrix<3, 3>& defgrad, - const double temperature, const Core::LinAlg::Matrix<10, 1>& x, + Core::LinAlg::Matrix<10, 1> viscoplastic_correction( + const InelasticDefgradTransvIsotropElastViscoplastUtils::LocalIntegrationDeformationTensors& + deftensors, + const double temperature, InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status); /*! @@ -1874,22 +1834,22 @@ namespace Mat * @note The method does not perform local substepping internally, but only determines the * solution of a single substep in the substep loop. * - * @param[in] CM right Cauchy-Green deformation tensor at current time instant + * @param[in] deftensors deformation tensors used for local time integration * @param[in] temperature absolute temperature * @param[in] last_plastic_strain plastic strain at the previous time instant - * @param[in] last_iFinM inverse inelastic deformation gradient at the previous time instant * @param[in] dt time step size to use for evaluation - * @param[in,out] sol current (in) / updated (out) solution of the Local Newton Loop - * @param[in,out] err_status error status + * @param[out] err_status error status + * @return solution of the Local Newton Loop */ - void local_newton_loop(const Core::LinAlg::Matrix<3, 3>& CM, const double temperature, - const double last_plastic_strain, const Core::LinAlg::Matrix<3, 3>& last_iFinM, - const double dt, Core::LinAlg::Matrix<10, 1>& sol, + Core::LinAlg::Matrix<10, 1> local_newton_loop( + const InelasticDefgradTransvIsotropElastViscoplastUtils::LocalIntegrationDeformationTensors& + deftensors, + const double temperature, const double last_plastic_strain, const double dt, InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status); /*! - * @brief History variables computed by the return mapping procedure. + * @brief History variables computed by the constitutive update procedure. */ struct HistoryVariables { @@ -1900,7 +1860,7 @@ namespace Mat }; /*! - * @brief Performs return mapping (elastic predictor - viscoplastic / plastic corrector + * @brief Performs constitutive update (elastic predictor - viscoplastic corrector * procedure) for the current GP and updates the current values of the time_step_quantities_. * It first evaluates whether the elastic predictor is a consistent * solution, and performs the local time integration (Local Newton Loop) afterwards if that is @@ -1912,10 +1872,10 @@ namespace Mat * @param[in] temperature current absolute temperature. Stored in time_step_quantities_. * @return the history variables * - * @note After a return_mapping, the state_quantitities_ are valid for the current GP and + * @note After a constitutive_update, the state_quantitities_ are valid for the current GP and * state defined by FredM and temperature. */ - HistoryVariables return_mapping( + HistoryVariables constitutive_update( const Core::LinAlg::Matrix<3, 3>& FredM, const double temperature); /** @@ -2028,7 +1988,7 @@ namespace Mat * * * @param[in] err_status error status - * @param[out] eval_action action to be performed subsequently in the Local Newton Loop + * @param[out] eval_action action to be performed subsequently in the local Newton Loop */ void manage_evaluation( const InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status, @@ -2082,17 +2042,48 @@ namespace Mat const Core::LinAlg::Matrix<3, 3>& FredM, const double temperature); /*! - * @brief Get an extensive error message to be displayed when the - * simulation terminates. This is useful for debugging the time - * integration in more detail. This message contains a base error - * message which describes what failed in short form - this is - * then extended with information on the element ID, the Gauss - * Point, the last_ values and so on... + * @brief Gets extensive error / warning message to be displayed, which is useful for debugging + * the time integration in more detail. This message contains a base error message which + * describes what failed in short form - this is then extended with information on the element + * ID, the Gauss Point, the last_ values and so on... * * @param[in] base_error_string base error message to be extended * with further information */ - [[nodiscard]] std::string get_error_info(const std::string& base_error_string) const; + [[nodiscard]] std::string get_error_warning_info(const std::string& base_error_string) const; + + /// ensure an error-free evaluation status -> throws if this is not the case + void ensure_error_free_evaluation( + const InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status) const + { + if (err_status != InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType::no_errors) + { + FOUR_C_THROW( + "{}", std::format("Unhandled error with status {}! This method should not be called!", + EnumTools::enum_name(err_status))); + } + } + + + /*! + * @brief Determines the initial estimate to be used within the Local Newton. + * If adaptive estimate interpolation is used, this method also prepares everything for the + * further re-estimations. + * + * @param[in] dt time step / substep size + * @param[in] deftensors deformation tensors used for local time integration + * @param[in] last_plastic_strain equivalent plastic strain at the previously converged + * time instant + * @param[in] err_status error status after the procedure + * @return initial estimate containing the inverse inelastic defgrad (components 0 - 8), and + * the equivalent plastic strain (component 9) for the Local Newton within this time step / + * substep + */ + [[nodiscard]] Core::LinAlg::Matrix<10, 1> determine_local_newton_init_estimate(const double dt, + const InelasticDefgradTransvIsotropElastViscoplastUtils::LocalIntegrationDeformationTensors& + deftensors, + const double last_plastic_strain, + const InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status) const; }; } // namespace Mat diff --git a/src/mat/4C_mat_inelastic_defgrad_factors_service.cpp b/src/mat/4C_mat_inelastic_defgrad_factors_service.cpp index 4009b8a51b4..997aacec9ad 100644 --- a/src/mat/4C_mat_inelastic_defgrad_factors_service.cpp +++ b/src/mat/4C_mat_inelastic_defgrad_factors_service.cpp @@ -278,6 +278,11 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::TimeStepQuantities: void Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::TimeStepQuantities::pre_evaluate( const unsigned int gp) { + FOUR_C_ASSERT_ALWAYS(gp < last_plastic_defgrad_inverse.size(), + "You try to pre-evaluate the time step quantities at GP {}, but the object has only {} Gauss " + "points", + gp, last_plastic_defgrad_inverse.size()); + // set consistent last substep values last_substep_plastic_defgrad_inverse[gp] = last_plastic_defgrad_inverse[gp]; last_substep_plastic_strain[gp] = last_plastic_strain[gp]; @@ -285,17 +290,23 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::TimeStepQuantities: /*--------------------------------------------------------------------* *--------------------------------------------------------------------*/ -void Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::TimeStepQuantities::update() +void Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::TimeStepQuantities::update( + const unsigned int gp) { + FOUR_C_ASSERT_ALWAYS(gp < last_plastic_defgrad_inverse.size(), + "You try to update the time step quantities at GP {}, but the object has only {} Gauss " + "points", + gp, last_plastic_defgrad_inverse.size()); + // update history variables for the next time step - last_defgrad = current_defgrad; - last_rightCG = current_rightCG; - last_plastic_defgrad_inverse = current_plastic_defgrad_inverse; - last_substep_plastic_defgrad_inverse = current_plastic_defgrad_inverse; - last_plastic_strain = current_plastic_strain; - last_equiv_stress = current_equiv_stress; - last_substep_plastic_strain = current_plastic_strain; - last_temperature = current_temperature; + last_defgrad[gp] = current_defgrad[gp]; + last_rightCG[gp] = current_rightCG[gp]; + last_plastic_defgrad_inverse[gp] = current_plastic_defgrad_inverse[gp]; + last_substep_plastic_defgrad_inverse[gp] = current_plastic_defgrad_inverse[gp]; + last_plastic_strain[gp] = current_plastic_strain[gp]; + last_substep_plastic_strain[gp] = current_plastic_strain[gp]; + last_equiv_stress[gp] = current_equiv_stress[gp]; + last_temperature[gp] = current_temperature[gp]; } @@ -406,8 +417,14 @@ Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonManager::Loca // know it at this point in time curr_num_iters_.resize(1, 0); - // set initial number of iterations to 0 + // set initial number of iterations iter_ = 0; + + // initialize solution vector and convergence quantities with dummy values; they will be set + // anyway to more meaningful values when starting the local Newton within the material model + sol_ = Core::LinAlg::Matrix<10, 1>(Core::LinAlg::Initialization::zero); + convergence_quantities_.residual_norm = 0.0; + convergence_quantities_.increment_norm = 0.0; } /*--------------------------------------------------------------------* @@ -441,9 +458,123 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonManager: /*--------------------------------------------------------------------* *--------------------------------------------------------------------*/ -void Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonManager::reset() +void Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonManager:: + reset_curr_num_iters(const unsigned int gp) { - std::ranges::fill(curr_num_iters_, 0); + FOUR_C_ASSERT_ALWAYS(gp < curr_num_iters_.size(), + "You try to reset the current number of iterations within the Local Newton manager at Gauss " + "point {}, but the object only has {} Gauss points", + gp, curr_num_iters_.size()); + + curr_num_iters_[gp] = 0; +} + + +/*--------------------------------------------------------------------* + *--------------------------------------------------------------------*/ +void Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonManager:: + save_init_estimate_and_reset_convergence_quantities( + const Core::LinAlg::Matrix<10, 1>& init_estimate) +{ + // --> set initial estimate + sol_ = init_estimate; + + // --> set quantities used for convergence checks + + // residual norm + convergence_quantities_.residual_norm = 0.0; + // if the convergence check requires verifying the residual norm, we must ensure that the value + // set here is larger than the tolerance, to perform the check at least once, in the next + // iteration + if (params_.conv_check == LocalNewtonConvCheck::residual || + params_.conv_check == LocalNewtonConvCheck::residual_and_increment_ratio) + { + convergence_quantities_.residual_norm = 2.0 * params_.res_tol; + } + + // increment norm: ratio of increment to current solution + convergence_quantities_.increment_norm = 0.0; + // if the convergence check requires verifying the increment norm, we must ensure that the value + // set here is larger than the tolerance, to perform the check at least once, in the next + // iteration + if (params_.conv_check == LocalNewtonConvCheck::increment_ratio || + params_.conv_check == LocalNewtonConvCheck::residual_and_increment_ratio) + { + convergence_quantities_.increment_norm = 2.0 * params_.incr_tol; + } +} + +/*--------------------------------------------------------------------* + *--------------------------------------------------------------------*/ +void Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonManager:: + increment_solution_vector(const Core::LinAlg::Matrix<10, 1>& delta_sol) +{ + sol_.update(1.0, delta_sol, 1.0); + + const double sol_norm = sol_.norm2(); + const double delta_sol_norm = delta_sol.norm2(); + FOUR_C_ASSERT_ALWAYS(sol_norm >= 1.0e-8, + "The solution vector in local iteration {} is nearly 0, with 2-norm: {}! Something went " + "wrong, since such mechanical states are not expected!", + iter_, sol_norm); + convergence_quantities_.increment_norm = delta_sol_norm / sol_norm; +} + +/*--------------------------------------------------------------------* + *--------------------------------------------------------------------*/ +bool Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonManager:: + is_local_newton_converged() const +{ + // check for convergence + switch (params_.conv_check) + { + case InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvCheck::residual: + return (convergence_quantities_.residual_norm <= params_.res_tol); + break; + case InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvCheck::increment_ratio: + return (convergence_quantities_.increment_norm <= params_.incr_tol); + break; + case InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvCheck:: + residual_and_increment_ratio: + return (convergence_quantities_.residual_norm <= params_.res_tol && + convergence_quantities_.increment_norm <= params_.incr_tol); + break; + default: + FOUR_C_THROW("You should not be here (convergence checking of the Local Newton Loop)"); + } +} + +/*--------------------------------------------------------------------* + *--------------------------------------------------------------------*/ +bool Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonManager:: + is_local_newton_stuck() const +{ + // check for "stuck" Local Newton, i.e., the increment does not change much but there is not a + // converged state (check only feasible after the first iteration, since dx must be available) + if ((iter_ > 0) && (convergence_quantities_.increment_norm < 1.0e-15)) + { + // only in the case that the residual is verified, we set an + // error status + switch (params_.conv_check) + { + case LocalNewtonConvCheck::residual: + case LocalNewtonConvCheck::residual_and_increment_ratio: + { + return (convergence_quantities_.residual_norm > params_.res_tol); + } + case LocalNewtonConvCheck::increment_ratio: + { + return false; + } + default: + FOUR_C_THROW( + "You should not be here with convergence check type {} (check: is Local Newton " + "stuck?)", + EnumTools::enum_name(params_.conv_check)); + } + } + + return false; } @@ -464,6 +595,20 @@ void Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonManager: extract_from_pack(buffer, curr_num_iters_); } +/*--------------------------------------------------------------------* + *--------------------------------------------------------------------*/ +Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalIntegrationDeformationTensors:: + LocalIntegrationDeformationTensors( + const Core::LinAlg::Matrix<3, 3>& F, const Core::LinAlg::Matrix<3, 3>& last_iFp) +{ + defgrad = F; + inv_defgrad.invert(defgrad); + right_cg.multiply_tn(1.0, defgrad, defgrad, 0.0); + elastic_predictor_inverse_plastic_defgrad = last_iFp; + elastic_predictor_elastic_defgrad.multiply( + 1.0, defgrad, elastic_predictor_inverse_plastic_defgrad, 0.0); +} + FOUR_C_NAMESPACE_CLOSE diff --git a/src/mat/4C_mat_inelastic_defgrad_factors_service.hpp b/src/mat/4C_mat_inelastic_defgrad_factors_service.hpp index 5d510484d18..a118b70345d 100644 --- a/src/mat/4C_mat_inelastic_defgrad_factors_service.hpp +++ b/src/mat/4C_mat_inelastic_defgrad_factors_service.hpp @@ -12,6 +12,7 @@ #include "4C_comm_utils.hpp" #include "4C_linalg_fixedsizematrix.hpp" +#include "4C_mat_multiplicative_split_defgrad_elasthyper_service.hpp" #include "4C_utils_exceptions.hpp" #include @@ -160,6 +161,27 @@ namespace Mat }; + /// struct: settings for registering errors within the procedures used for the constitutive + /// update + struct ErrorRegistrationSettings + { + //! should overflow error be registered via ErrorType when the plastic strain increment + //! exceeds the specified tolerance? + bool register_plastic_strain_incr_overflow; + + //! maximum, numerically evaluable plastic strain increment before overflow error is + //! registered? + double max_plastic_strain_incr; + + //! should overflow error be registered via ErrorType when any of the plastic strain + //! derivative increments exceeds the specified tolerance? + bool register_plastic_strain_deriv_incr_overflow; + + //! maximum, numerically evaluable increment of plastic strain derivatives (time_step * + //! derivative) + double max_plastic_strain_deriv_incr; + }; + /// enum class for evaluation management actions in the iterations of the /// Local Newton loop enum class EvaluationAction @@ -295,8 +317,8 @@ namespace Mat */ void pre_evaluate(const unsigned int gp); - //! Update values between time steps: last <- current - void update(); + //! Update values between time steps: last <- current, at a given Gauss points + void update(const unsigned int gp); //! Pack values void pack(Core::Communication::PackBuffer& data) const; @@ -410,7 +432,7 @@ namespace Mat [[nodiscard]] std::string get_info() const { std::string out; - out += "Substepping info: \n"; + out += "\nSubstepping info: \n"; out += std::format( "t: {}, substep_counter: {}, curr_dt: {}, time_step_halving_counter: {}, " "total_num_of_substeps: {} \n", @@ -467,6 +489,9 @@ namespace Mat //! isotropic constitutive tensor factors Core::LinAlg::Matrix<8, 1> curr_delta{Core::LinAlg::Initialization::zero}; + //! thermal contribution due to thermal expansion to the thermo-elastic 2PK stress + TensorAndTemperatureDerivative curr_ST{}; + //! elastic 2nd PK stress tensors (specifically only transversely-isotropic components) Core::LinAlg::Matrix<3, 3> curr_SeM{Core::LinAlg::Initialization::zero}; @@ -821,7 +846,7 @@ namespace Mat double residual_norm; //! ratio of solution increment to current solution: \f$ \frac{\left| \Delta - //! \boldsymbol{s}^{l+1} \right|}{\left| \boldsymbol{s}^{l} \right|} \f$ + //! \boldsymbol{s}^{l} \right|}{\left| \boldsymbol{s}^{l} \right|} \f$ double increment_norm; }; @@ -831,29 +856,29 @@ namespace Mat struct LocalNewtonParams { //! convergence tolerance: absolute residual value - const double res_tol; + double res_tol; //! convergence tolerance: ratio of solution increment to current solution - const double incr_tol; + double incr_tol; //! convergence check strategy - const LocalNewtonConvCheck conv_check; + LocalNewtonConvCheck conv_check; //! strategy for dealing with divergence - const LocalNewtonDiverCont diver_cont; + LocalNewtonDiverCont diver_cont; //! maximum number of local iterations - const unsigned int max_iter; + int max_iter; //! maximum exceedance factor for the residual tolerance (to be used when //! employing the divergence management strategy for continuation with //! safeguard) - const double max_exceedance_fact_res_tol; + double max_exceedance_fact_res_tol; //! maximum exceedance factor for the solution increment tolerance (to be used when //! employing the divergence management strategy for continuation with //! safeguard) - const double max_exceedance_fact_incr_tol; + double max_exceedance_fact_incr_tol; }; //! class for managing the Local Newton loop, containing the utilized parameters and iteration @@ -876,9 +901,6 @@ namespace Mat /// getter for local iteration count [[nodiscard]] unsigned int iter() const { return iter_; } - /// setter for local iteration count - void set_iteration_count(const unsigned int iter) { iter_ = iter; } - /// getter for total number of local iterations evaluated in this time step (vector over all /// Gauss points) [[nodiscard]] const std::vector& curr_num_iters() const @@ -886,9 +908,6 @@ namespace Mat return curr_num_iters_; } - /// increment iteration count by 1 - void increment_iteration_count() { iter_++; } - /*! * @brief Resizing based on a given number of Gauss points * @@ -896,6 +915,76 @@ namespace Mat */ void resize(const unsigned int numgp); + /*! + * @brief Initialize the solution vector and the convergence quantities, for the + * subsequent Local Newton at the currently considered Gauss point + * + * @param[in] init_estimate initial estimate \f$ \boldsymbol{s}^{(0)} \f$ + */ + void save_init_estimate_and_reset_convergence_quantities( + const Core::LinAlg::Matrix<10, 1>& init_estimate); + + /// reset iteration counter + void reset_iter() { iter_ = 0; } + + /// sets the residual norm based on the given residual vector + void set_residual_norm(const Core::LinAlg::Matrix<10, 1>& residual) + { + convergence_quantities_.residual_norm = residual.norm2(); + } + + /*! + * @brief Determine whether the Local Newton Loop has converged, based on the saved + * convergence quantities and the specified convergence checks. + * + * @return boolean: true = converged + */ + [[nodiscard]] bool is_local_newton_converged() const; + + + /*! + * @brief After an unsuccessful convergence check: determine whether the Local Newton is + * stuck / stagnates, i.e., the relative solution increment is nearly 0, but there is no + * convergence yet, based on the saved convergence quantities. + * + * @return boolean: true = stuck + */ + [[nodiscard]] bool is_local_newton_stuck() const; + + + /// is the maximum number of iterations reached? + [[nodiscard]] bool is_max_iter_reached() + { + return iter_ >= static_cast(params_.max_iter); + } + + + /// increment iteration counter + void increment_iter() { ++iter_; } + + /*! + * @brief Increments the solution vector \f$ \boldsymbol{s}^{(l+1)} = \boldsymbol{s}^{(l)} + * + + * \Delta \boldsymbol{s}^{(l+1)} \f$ after the current iteration \f$ l \f$ + * + * @note Also updates the increment norm (ratio of increment to solution) internally based on + * the provided increment + * + * @param[in] delta_sol increment vector for the next iteration \f$\Delta + * \boldsymbol{s}^{(l+1)}\f$ + */ + void increment_solution_vector(const Core::LinAlg::Matrix<10, 1>& delta_sol); + + /// getter for the solution vector + [[nodiscard]] Core::LinAlg::Matrix<10, 1> sol() const { return sol_; } + + + /// getter for the convergence quantities + [[nodiscard]] LocalNewtonConvQuantities convergence_quantities() const + { + return convergence_quantities_; + } + /*! * @brief Routine to be run after the Local Newton-Raphson at a given Gauss point * @@ -903,8 +992,8 @@ namespace Mat */ void update_after_local_newton(const unsigned int gp); - //! reset method - void reset(); + //! reset the saved number of iterations at a given Gauss point + void reset_curr_num_iters(const unsigned int gp); //! pack values void pack(Core::Communication::PackBuffer& data) const; @@ -922,12 +1011,50 @@ namespace Mat //! total number of local iterations for the current timestep; vector of Gauss point values std::vector curr_num_iters_; + //! solution vector in the current iteration \f$ \boldsymbol{s}^{(l)} \f$ (at the + //! currently considered Gauss point) + Core::LinAlg::Matrix<10, 1> sol_; + + //! quantities used for convergence checks + LocalNewtonConvQuantities convergence_quantities_; + //! tracks whether the resizing function has been called, to set the current number of //! Gauss points exactly once! bool resize_called_{false}; }; + //! helper struct containing deformation tensors passed as input + //! for the local time integration + struct LocalIntegrationDeformationTensors + { + /*! + * @brief constructor + * + * @param[in] F deformation gradient \f$ \mathbf{F}_{n+1} \f$ + * @param[in] last_iFp previous inverse inelastic/plastic deformation gradient \f$ + \mathbf{F}_{\text{p},n}^{-1} \f$ + * + */ + LocalIntegrationDeformationTensors( + const Core::LinAlg::Matrix<3, 3>& F, const Core::LinAlg::Matrix<3, 3>& last_iFp); + + //! deformation gradient \f$ \mathbf{F}_{n+1} \f$ + Core::LinAlg::Matrix<3, 3> defgrad; + + //! inverse deformation gradient \f$ \mathbf{F}_{n+1}^{-1} \f$ + Core::LinAlg::Matrix<3, 3> inv_defgrad; + //! right Cauchy-Green deformation tensor \f$ \mathbf{C}_{n+1} \f$ + Core::LinAlg::Matrix<3, 3> right_cg; + + //! inverse plastic deformation gradient within the elastic predictor \f$ + //! \left[ \mathbf{F}_{\mathrm{p},n+1}^{(\mathrm{E})} \right]^{-1} \f$ + Core::LinAlg::Matrix<3, 3> elastic_predictor_inverse_plastic_defgrad; + + //! elastic deformation gradient within the elastic predictor \f$ + //! \mathbf{F}_{\mathrm{e},n+1}^{(\mathrm{E})} \f$ + Core::LinAlg::Matrix<3, 3> elastic_predictor_elastic_defgrad; + }; } // namespace InelasticDefgradTransvIsotropElastViscoplastUtils diff --git a/src/mat/4C_mat_material_factory.cpp b/src/mat/4C_mat_material_factory.cpp index 6e0924609c0..c9b20a9bdf8 100644 --- a/src/mat/4C_mat_material_factory.cpp +++ b/src/mat/4C_mat_material_factory.cpp @@ -129,6 +129,7 @@ #include "4C_mat_scatra_reaction.hpp" #include "4C_mat_scl.hpp" #include "4C_mat_shell_kl.hpp" +#include "4C_mat_solid_superposition.hpp" #include "4C_mat_soret.hpp" #include "4C_mat_spring.hpp" #include "4C_mat_structporo.hpp" @@ -1028,6 +1029,10 @@ std::unique_ptr Mat::make_parameter( { return make_parameter_impl(id, type, input_data); } + case Core::Materials::m_superposition: + { + return make_parameter_impl(id, type, input_data); + } case Core::Materials::m_linelast1D: { return make_parameter_impl(id, type, input_data); diff --git a/src/mat/4C_mat_mixture.cpp b/src/mat/4C_mat_mixture.cpp index e1c75eb0c65..735b43ada85 100644 --- a/src/mat/4C_mat_mixture.cpp +++ b/src/mat/4C_mat_mixture.cpp @@ -133,8 +133,6 @@ void Mat::Mixture::unpack(Core::Communication::UnpackBuffer& buffer) constituents_->clear(); setup_ = false; - - Core::Communication::extract_and_assert_id(buffer, unique_par_object_id()); // matid and recover params_ @@ -161,7 +159,6 @@ void Mat::Mixture::unpack(Core::Communication::UnpackBuffer& buffer) // Extract setup flag extract_from_pack(buffer, setup_); - // Extract is isPreEvaluated std::vector isPreEvaluatedInt; extract_from_pack(buffer, isPreEvaluatedInt); diff --git a/src/mat/4C_mat_multiplicative_split_defgrad_elasthyper.cpp b/src/mat/4C_mat_multiplicative_split_defgrad_elasthyper.cpp index 357ff679f64..86d56353a28 100644 --- a/src/mat/4C_mat_multiplicative_split_defgrad_elasthyper.cpp +++ b/src/mat/4C_mat_multiplicative_split_defgrad_elasthyper.cpp @@ -15,6 +15,7 @@ #include "4C_linalg_fixedsizematrix_tensor_products.hpp" #include "4C_linalg_fixedsizematrix_voigt_notation.hpp" #include "4C_linalg_symmetric_tensor.hpp" +#include "4C_linalg_tensor.hpp" #include "4C_linalg_tensor_conversion.hpp" #include "4C_linalg_tensor_generators.hpp" #include "4C_mat_anisotropy.hpp" @@ -28,6 +29,7 @@ #include "4C_ssi_input.hpp" #include "4C_structure_new_enum_lists.hpp" #include "4C_utils_enum.hpp" +#include "4C_utils_exceptions.hpp" #include @@ -45,7 +47,10 @@ Mat::PAR::MultiplicativeSplitDefgradElastHyper::MultiplicativeSplitDefgradElastH matids_elast_(matdata.parameters.get>("MATIDSEL")), numfac_inel_(matdata.parameters.get("NUMFACINEL")), inel_defgradfacids_(matdata.parameters.get>("INELDEFGRADFACIDS")), - density_(matdata.parameters.get("DENS")) + density_(matdata.parameters.get("DENS")), + ref_temperature_(matdata.parameters.get("REF_TEMPERATURE")), + thermal_expansion_coefficient_( + matdata.parameters.get("THERMAL_EXPANSION_COEFFICIENT")) { // check if sizes fit if (nummat_elast_ != static_cast(matids_elast_.size())) @@ -83,7 +88,7 @@ Core::Communication::ParObject* Mat::MultiplicativeSplitDefgradElastHyperType::c /*--------------------------------------------------------------------* *--------------------------------------------------------------------*/ Mat::MultiplicativeSplitDefgradElastHyper::MultiplicativeSplitDefgradElastHyper() - : anisotropy_(std::make_shared()), + : anisotropy_(), inelastic_(std::make_shared()), params_(nullptr), potsumel_(0), @@ -95,7 +100,7 @@ Mat::MultiplicativeSplitDefgradElastHyper::MultiplicativeSplitDefgradElastHyper( *--------------------------------------------------------------------*/ Mat::MultiplicativeSplitDefgradElastHyper::MultiplicativeSplitDefgradElastHyper( Mat::PAR::MultiplicativeSplitDefgradElastHyper* params) - : anisotropy_(std::make_shared()), + : anisotropy_(), inelastic_(std::make_shared()), params_(params), potsumel_(0), @@ -115,7 +120,7 @@ Mat::MultiplicativeSplitDefgradElastHyper::MultiplicativeSplitDefgradElastHyper( { potsumel_.push_back(elastic_summand); } - elastic_summand->register_anisotropy_extensions(*anisotropy_); + elastic_summand->register_anisotropy_extensions(anisotropy_); } inelastic_->assign_to_source(params); @@ -133,7 +138,7 @@ void Mat::MultiplicativeSplitDefgradElastHyper::pack(Core::Communication::PackBu if (params_ != nullptr) matid = params_->id(); // in case we are in post-process mode add_to_pack(data, matid); - anisotropy_->pack_anisotropy(data); + anisotropy_.pack_anisotropy(data); Core::Communication::PotentiallyUnusedBufferScope summand_scope{data}; if (params_ != nullptr) // summands are not accessible in postprocessing mode @@ -178,7 +183,7 @@ void Mat::MultiplicativeSplitDefgradElastHyper::unpack(Core::Communication::Unpa } } - anisotropy_->unpack_anisotropy(buffer); + anisotropy_.unpack_anisotropy(buffer); Core::Communication::PotentiallyUnusedBufferScope summand_scope{buffer}; if (params_ != nullptr) // summands are not accessible in postprocessing mode @@ -206,7 +211,7 @@ void Mat::MultiplicativeSplitDefgradElastHyper::unpack(Core::Communication::Unpa for (const auto& elastic_summand : potsumel_) { elastic_summand->unpack_summand(buffer); - elastic_summand->register_anisotropy_extensions(*anisotropy_); + elastic_summand->register_anisotropy_extensions(anisotropy_); } for (const std::shared_ptr& elastic_summand : potsumel_transviso_) @@ -241,9 +246,20 @@ void Mat::MultiplicativeSplitDefgradElastHyper::evaluate( Mat::calculate_gamma_delta(stress_factors.gamma, stress_factors.delta, kinematic_quantities.prinv, kinematic_quantities.dPIe, kinematic_quantities.ddPIIe); + // compute thermal quantities from the absolute temperature stored in the parameter list + double delta_temperature = 0.0; + if (params.isParameter("temperature")) + { + delta_temperature = params.get("temperature") - params_->ref_temperature_; + } + auto thermoelastic_stress_contribution = + Mat::ThermalExpansion::compute_thermoelastic_stress_contribution( + delta_temperature, params_->thermal_expansion_coefficient_, potsumel_, gp, eleGID); + // derivative of 2nd Piola Kirchhoff stresses w.r.t. the inverse inelastic deformation // gradient - Core::LinAlg::Matrix<6, 9> dSdiFin = evaluated_sdi_fin(kinematic_quantities, stress_factors); + Core::LinAlg::Matrix<6, 9> dSdiFin = evaluate_d_stress_d_ifin( + kinematic_quantities, stress_factors, thermoelastic_stress_contribution.value); // right Cauchy-Green deformation tensor Core::LinAlg::Matrix<3, 3> CM(Core::LinAlg::Initialization::zero); @@ -255,9 +271,18 @@ void Mat::MultiplicativeSplitDefgradElastHyper::evaluate( // cmat = 2 dS/dC = 2 \frac{\partial S}{\partial C} + 2 \frac{\partial S}{\partial F_{in}^{-1}} // : \frac{\partial F_{in}^{-1}}{\partial C} = cmatiso + cmatadd evaluate_stress_cmat_iso(kinematic_quantities, stress_factors, stress_view, cmatiso); + + // subtract stress contribution due to thermal expansion + stress -= Mat::ThermalExpansion::compute_pk2_stress_contribution( + thermoelastic_stress_contribution, kinematic_quantities.iFinM) + .value; + // separate update coming from the transversely isotropic components if (!(potsumel_transviso_.empty())) { + FOUR_C_ASSERT_ALWAYS(delta_temperature == 0.0, + "Thermoelastic coupling with transversely isotropic elastic summands is not supported yet. " + "Use isotropic elastic summands only."); evaluate_transv_iso_quantities( kinematic_quantities, CM, params, gp, eleGID, stress_view, cmatiso, dSdiFin); } @@ -300,13 +325,36 @@ Mat::MultiplicativeSplitDefgradElastHyper::evaluate_d_stress_d_scalar( Mat::calculate_gamma_delta(stress_factors.gamma, stress_factors.delta, kinematic_quantities.prinv, kinematic_quantities.dPIe, kinematic_quantities.ddPIIe); - Core::LinAlg::SymmetricTensor d_stress_d_scalar{}; - Core::LinAlg::Matrix<6, 1> d_stress_d_scalar_view = - Core::LinAlg::make_stress_like_voigt_view(d_stress_d_scalar); + double delta_temperature = 0.0; + + // compute thermal quantities from the absolute temperature stored in the parameter list + if (params.isParameter("temperature")) + { + delta_temperature = params.get("temperature") - params_->ref_temperature_; + } + + const auto thermoelastic_stress_contribution = + Mat::ThermalExpansion::compute_thermoelastic_stress_contribution( + delta_temperature, params_->thermal_expansion_coefficient_, potsumel_, gp, eleGID); + + Core::LinAlg::Matrix<6, 9> dSdiFin = evaluate_d_stress_d_ifin( + kinematic_quantities, stress_factors, thermoelastic_stress_contribution.value); + + Core::LinAlg::SymmetricTensor d_stress_d_scalar = + make_symmetric_tensor_from_stress_like_voigt_matrix( + evaluate_od_stiff_mat(source, &defgrad_mat, dSdiFin)); + + + if (source == PAR::InelasticSource::temperature) + { + // stress depends on temperature not only through the inelastic deformation gradient but also + // through thermal expansion + d_stress_d_scalar -= Mat::ThermalExpansion::compute_pk2_stress_contribution( + thermoelastic_stress_contribution, kinematic_quantities.iFinM) + .temperature_derivative; + } - Core::LinAlg::Matrix<6, 9> dSdiFin = evaluated_sdi_fin(kinematic_quantities, stress_factors); - evaluate_od_stiff_mat(source, &defgrad_mat, dSdiFin, d_stress_d_scalar_view); return d_stress_d_scalar; } @@ -644,8 +692,12 @@ void Mat::MultiplicativeSplitDefgradElastHyper::evaluate_kin_quant_elast( Core::LinAlg::Voigt::matrix_3x3_to_9x1(CiFiniCeM, CiFiniCe9x1); // derivatives of the elastic right CG + Core::LinAlg::SymmetricTensor dCedC_tensor; + Core::LinAlg::Tensor dCediFin_tensor; Mat::elast_hyper_get_derivs_of_elastic_right_cg_tensor(Core::LinAlg::make_tensor(iFinM), - Core::LinAlg::assume_symmetry(Core::LinAlg::make_tensor(CM)), dCedC, dCediFin); + Core::LinAlg::assume_symmetry(Core::LinAlg::make_tensor(CM)), dCedC_tensor, dCediFin_tensor); + dCedC = Core::LinAlg::make_6x6_voigt_matrix_from_tensor(dCedC_tensor); + dCediFin = Core::LinAlg::make_6x9_voigt_matrix_from_tensor(dCediFin_tensor); } /*--------------------------------------------------------------------* @@ -668,9 +720,10 @@ void Mat::MultiplicativeSplitDefgradElastHyper::evaluate_invariant_derivatives( /*--------------------------------------------------------------------* *--------------------------------------------------------------------*/ -Core::LinAlg::Matrix<6, 9> Mat::MultiplicativeSplitDefgradElastHyper::evaluated_sdi_fin( +Core::LinAlg::Matrix<6, 9> Mat::MultiplicativeSplitDefgradElastHyper::evaluate_d_stress_d_ifin( const Mat::MultiplicativeSplitDefgradElastHyper::KinematicQuantities& kinemat_quant, - const Mat::StressFactors& stress_fact) const + const Mat::StressFactors& stress_fact, + const Core::LinAlg::SymmetricTensor& SthetaT) const { // declare output variables Core::LinAlg::Matrix<6, 9> dSdiFin{Core::LinAlg::Initialization::zero}; @@ -735,6 +788,22 @@ Core::LinAlg::Matrix<6, 9> Mat::MultiplicativeSplitDefgradElastHyper::evaluated_ // chain rule to get dS/d(det(Fin)) * d(det(Fin))/diFin dSdiFin.multiply_nt(1.0, dSddetFin, ddetFindiFinV, 1.0); + { + const Core::LinAlg::Tensor iFinSthetaT = dot(make_tensor_view(iFinM), SthetaT); + + /// \f$\texttt{dSdiFin}\; \mathrel{-}= \frac{\partial}{\partial + /// \mathbf{F}_{\text{in}}^{-1}}\left(\det(\mathbf{F}_{\text{in}}) \mathbf{F}_{\text{in}}^{-1} + /// \cdot \mathbf{S}_{\theta,T} \cdot \mathbf{F}_{\text{in}}^{-T}\right)\f$ + Core::LinAlg::FourTensorOperations::add_right_non_symmetric_holzapfel_product( + dSdiFin, id, make_matrix_view(iFinSthetaT), -detFin); + + Core::LinAlg::Matrix<3, 3> iFinSthetaTiFinT(Core::LinAlg::Initialization::zero); + iFinSthetaTiFinT.multiply_nt(1.0, make_matrix_view(iFinSthetaT), iFinM, 0.0); + Core::LinAlg::Matrix<6, 1> iFinSthetaTiFinTV(Core::LinAlg::Initialization::zero); + Core::LinAlg::Voigt::Stresses::matrix_to_vector(iFinSthetaTiFinT, iFinSthetaTiFinTV); + dSdiFin.multiply_nt(-1.0, iFinSthetaTiFinTV, ddetFindiFinV, 1.0); + } + return dSdiFin; } @@ -950,8 +1019,8 @@ void Mat::MultiplicativeSplitDefgradElastHyper::setup(const int numgp, const std::optional& coord_system) { // Read anisotropy - anisotropy_->set_number_of_gauss_points(numgp); - anisotropy_->read_anisotropy_from_element(fibers, coord_system); + anisotropy_.set_number_of_gauss_points(numgp); + anisotropy_.read_anisotropy_from_element(fibers, coord_system); // elastic materials for (const auto& summand : potsumel_) summand->setup(numgp, fibers, coord_system); @@ -979,12 +1048,11 @@ void Mat::MultiplicativeSplitDefgradElastHyper::update() /*--------------------------------------------------------------------* *--------------------------------------------------------------------*/ -void Mat::MultiplicativeSplitDefgradElastHyper::evaluate_od_stiff_mat(PAR::InelasticSource source, - const Core::LinAlg::Matrix<3, 3>* const defgrad, const Core::LinAlg::Matrix<6, 9>& dSdiFin, - Core::LinAlg::Matrix<6, 1>& dstressdx) +Core::LinAlg::Matrix<6, 1> Mat::MultiplicativeSplitDefgradElastHyper::evaluate_od_stiff_mat( + const PAR::InelasticSource source, const Core::LinAlg::Matrix<3, 3>* const defgrad, + const Core::LinAlg::Matrix<6, 9>& dSdiFin) { - // clear variable - dstressdx.clear(); + Core::LinAlg::Matrix<6, 1> dstressdx{Core::LinAlg::Initialization::zero}; // References to vector of inelastic contributions and inelastic deformation gradients const auto& facdefgradin = inelastic_->fac_def_grad_in(); @@ -1064,8 +1132,53 @@ void Mat::MultiplicativeSplitDefgradElastHyper::evaluate_od_stiff_mat(PAR::Inela } else FOUR_C_THROW("You should not be here"); + + return dstressdx; +} + +void Mat::MultiplicativeSplitDefgradElastHyper::stress_temperature_modulus_and_deriv( + Core::LinAlg::SymmetricTensor& stm, + Core::LinAlg::SymmetricTensor& stm_dT, const int gp) +{ + // this contribution is intentionally neglected so far. + stm.fill(0.0); + stm_dT.fill(0.0); } +Mat::HeatSource Mat::MultiplicativeSplitDefgradElastHyper::evaluate_additional_heat_source( + const EvaluationContext<3>& context, const int gp, const int eleGID, + const Core::LinAlg::Matrix<3, 3>* current_defgrad, const double current_temperature) +{ + HeatSource heat_source; + + // References to vector of inelastic contributions and inelastic deformation gradients + const auto& facdefgradin = inelastic_->fac_def_grad_in(); + + // number of contributions + const int num_contributions = inelastic_->num_inelastic_def_grad(); + + // check number of factors the inelastic deformation gradient consists of and choose + // implementation accordingly + if (num_contributions == 1) + { + if (const auto viscoplastic_factor = + std::dynamic_pointer_cast( + facdefgradin[0].second)) + { + heat_source = viscoplastic_factor->evaluate_taylor_quinney_heat_source(context, gp, eleGID, + current_defgrad, Core::LinAlg::identity_matrix<3>(), current_temperature); + } + } + else if (num_contributions > 1) + { + FOUR_C_THROW( + "Evaluation of additional heat source is only implemented for a single factor so far."); + } + else + FOUR_C_THROW("You should not be here"); + + return heat_source; +} /*--------------------------------------------------------------------* *--------------------------------------------------------------------*/ void Mat::MultiplicativeSplitDefgradElastHyper::pre_evaluate(const Teuchos::ParameterList& params, diff --git a/src/mat/4C_mat_multiplicative_split_defgrad_elasthyper.hpp b/src/mat/4C_mat_multiplicative_split_defgrad_elasthyper.hpp index 0eda8de8c97..6edcd09b248 100644 --- a/src/mat/4C_mat_multiplicative_split_defgrad_elasthyper.hpp +++ b/src/mat/4C_mat_multiplicative_split_defgrad_elasthyper.hpp @@ -11,12 +11,19 @@ #include "4C_config.hpp" #include "4C_comm_parobjectfactory.hpp" +#include "4C_linalg_fixedsizematrix.hpp" +#include "4C_linalg_symmetric_tensor.hpp" +#include "4C_linalg_tensor.hpp" #include "4C_mat_anisotropy.hpp" #include "4C_mat_elast_couptransverselyisotropic.hpp" -#include "4C_mat_monolithic_solid_scalar_material.hpp" #include "4C_mat_multiplicative_split_defgrad_elasthyper_service.hpp" #include "4C_mat_so3_material.hpp" +#include "4C_mat_thermomechanical.hpp" #include "4C_material_parameter_base.hpp" +#include "4C_utils_exceptions.hpp" + +#include +#include FOUR_C_NAMESPACE_OPEN @@ -65,6 +72,12 @@ namespace Mat /// material mass density const double density_; + /// reference temperature for thermal expansion + const double ref_temperature_; + + /// thermal expansion coefficient + const double thermal_expansion_coefficient_; + }; // class MultiplicativeSplitDefgrad_ElastHyper } // namespace PAR @@ -176,8 +189,7 @@ namespace Mat that are needed to set up the system to be solved are evaluated in the derived classes of the interface class 'InelasticDefgradFactors'. */ - class MultiplicativeSplitDefgradElastHyper : public So3Material, - public MonolithicSolidScalarMaterial + class MultiplicativeSplitDefgradElastHyper : public So3Material, public Trait::ThermoSolid { public: /// construct empty material object @@ -276,6 +288,112 @@ namespace Mat const Teuchos::ParameterList& params, const EvaluationContext<3>& context, int gp, int eleGID) override; + void reinit(const Core::LinAlg::Tensor* defgrd, + const Core::LinAlg::SymmetricTensor& glstrain, double temperature, + unsigned gp) override { /* do nothing */ }; + + void stress_temperature_modulus_and_deriv(Core::LinAlg::SymmetricTensor& stm, + Core::LinAlg::SymmetricTensor& stm_dT, const int gp) override; + + /*! + * @brief Evaluate the heat source produced by this material. Currently, this is only + * enabled for the viscoplastic factor. + * + * @param[in] context Evaluation context, providing access to the current timestep and total + * time + * @param[in] gp Gauss point + * @param[in] eleGID global element ID + * @param[in] defgrad Deformation gradient + * @param[in] current_temperature Absolute current temperature + * @return mechanical dissipation heat source and derivatives w.r.t. temperature and the right + * Cauchy-Green tensor + */ + [[nodiscard]] HeatSource evaluate_additional_heat_source(const EvaluationContext<3>& context, + const int gp, const int eleGID, const Core::LinAlg::Matrix<3, 3>* current_defgrad, + const double current_temperature); + + + // ******************************************************************************* + // All of the following functions in this block are only required since the ThermoSolid + // Trait inherits from the ThermoTrait. + // https://github.com/4C-multiphysics/4C/pull/2075 aims to remove this dependency. After this, + // these functions can be removed. This material hence does not wrap an internal thermo + // material, all corresponding functions throw an error if called. + + void evaluate( + const Core::LinAlg::Matrix<3, 1>& gradtemp, ///< temperature gradient (strain tensor) + Core::LinAlg::Matrix<3, 3>& cmat, ///< constitutive matrix + Core::LinAlg::Matrix<3, 1>& heatflux, ///< heatflux + const int eleGID) const override + { + FOUR_C_THROW("This material does not wrap an internal thermo material"); + }; + + void evaluate( + const Core::LinAlg::Matrix<2, 1>& gradtemp, ///< temperature gradient (strain tensor) + Core::LinAlg::Matrix<2, 2>& cmat, ///< constitutive matrix + Core::LinAlg::Matrix<2, 1>& heatflux, ///< heatflux + const int eleGID) const override + { + FOUR_C_THROW("This material does not wrap an internal thermo material"); + }; + + void evaluate( + const Core::LinAlg::Matrix<1, 1>& gradtemp, ///< temperature gradient (strain tensor) + Core::LinAlg::Matrix<1, 1>& cmat, ///< constitutive matrix + Core::LinAlg::Matrix<1, 1>& heatflux, ///< heatflux + const int eleGID) const override + { + FOUR_C_THROW("This material does not wrap an internal thermo material"); + }; + + std::vector conductivity(int eleGID = 0) const override + { + FOUR_C_THROW("This material does not wrap an internal thermo material"); + }; + + void conductivity_deriv_t(Core::LinAlg::Matrix<3, 3>& dCondDT) const override + { + FOUR_C_THROW("This material does not wrap an internal thermo material"); + }; + + void conductivity_deriv_t(Core::LinAlg::Matrix<2, 2>& dCondDT) const override + { + FOUR_C_THROW("This material does not wrap an internal thermo material"); + }; + + void conductivity_deriv_t(Core::LinAlg::Matrix<1, 1>& dCondDT) const override + { + FOUR_C_THROW("This material does not wrap an internal thermo material"); + }; + + double capacity() const override + { + FOUR_C_THROW("This material does not wrap an internal thermo material"); + }; + + double capacity_deriv_t() const override + { + FOUR_C_THROW("This material does not wrap an internal thermo material"); + }; + + void reinit(double temperature, unsigned gp) override + { + FOUR_C_THROW("This material does not wrap an internal thermo material"); + }; + + void reset_current_state() override + { + FOUR_C_THROW("This material does not wrap an internal thermo material"); + }; + + void commit_current_state() override + { + FOUR_C_THROW("This material does not wrap an internal thermo material"); + }; + + // ******************************************************************************* + double evaluate_cauchy_n_dir_and_derivatives(const Core::LinAlg::Tensor& defgrd, const Core::LinAlg::Tensor& n, const Core::LinAlg::Tensor& dir, Core::LinAlg::Matrix<3, 1>* d_cauchyndir_dn, Core::LinAlg::Matrix<3, 1>* d_cauchyndir_ddir, @@ -300,18 +418,23 @@ namespace Mat const std::string& name, Core::LinAlg::SerialDenseMatrix& data) const override; /*! - * @brief Evaluate off-diagonal stiffness matrix (required for monolithic algorithms) + * @brief Evaluate off-diagonal stiffness matrix contributions due to the inelastic deformation, + * i.e.: + * \f[ + * \frac{\partial \mathbf{S}}{\partial \mathbf{F}_\text{in}^{-1}} + * :\frac{\mathrm{d}\mathbf{F}_\text{in}^{-1}}{\mathrm{d}x} + * \f] + * where \f[x\f] is the scalar of the secondary field corresponding to \param source * * @param[in] source Source of inelastic deformation * @param[in] defgrad Deformation gradient - * @param[in] dSdiFin Derivative of 2nd Piola Kirchhoff stresses w.r.t. the inverse inelastic - * deformation gradient - * @param[out] dstressdx Derivative of 2nd Piola Kirchhoff stresses w.r.t. primary variable of - * different field + * @param[in] dSdiFin Already computed derivative of 2nd Piola Kirchhoff stresses w.r.t. the + * inverse inelastic deformation gradient \f[ \frac{\partial \mathbf{S}}{\partial + * \mathbf{F}_\text{in}^{-1}} \f] + * @return off-diagonal stiffness matrix contribution in stress-like Voigt notation */ - void evaluate_od_stiff_mat(PAR::InelasticSource source, - const Core::LinAlg::Matrix<3, 3>* defgrad, const Core::LinAlg::Matrix<6, 9>& dSdiFin, - Core::LinAlg::Matrix<6, 1>& dstressdx); + Core::LinAlg::Matrix<6, 1> evaluate_od_stiff_mat(PAR::InelasticSource source, + const Core::LinAlg::Matrix<3, 3>* defgrad, const Core::LinAlg::Matrix<6, 9>& dSdiFin); /*! * @brief Evaluate additional terms of the elasticity tensor @@ -337,11 +460,13 @@ namespace Mat * @param[in] kinemat_quant struct containing kinematic quantities * @param[in] stress_fact struct containing \f$ \gamma_i \f$ and \f$ \delta_i \f$ stress * factors, as presented in Holzapfel - Nonlinear Solid Mechanics + * @param[in] SthetaT thermal part of the thermo-elastic stress (due to thermal expansion) * @return derivative \f$ \frac{\partial \mathsymbol{S}}{\partial * \mathsymbol{F}^{-1}_{\text{in}}} \f$ */ - Core::LinAlg::Matrix<6, 9> evaluated_sdi_fin( - const KinematicQuantities& kinemat_quant, const Mat::StressFactors& stress_factors) const; + [[nodiscard]] Core::LinAlg::Matrix<6, 9> evaluate_d_stress_d_ifin( + const KinematicQuantities& kinemat_quant, const Mat::StressFactors& stress_factors, + const Core::LinAlg::SymmetricTensor& SthetaT) const; /*! * @brief Evaluate the stress and stiffness components of the transversely isotropic components @@ -379,7 +504,6 @@ namespace Mat * \f] * \f[ * \mathbf{S} = \det(\mathbf{F}_\text{in}) \left(\gamma_1 \ \mathbf{C}_\text{in}^{-1} + \gamma_2 - * \ * \mathbf{C}_\text{in}^{-1} \cdot \mathbf{C} \cdot \mathbf{C}_\text{in}^{-1} + \gamma_3 \ * \mathbf{C}^{-1} \right) * \f] with \f$\gamma_i\f$ as defined in Mat::CalculateGammaDelta() @@ -460,7 +584,7 @@ namespace Mat private: /// Holder for anisotropy - std::shared_ptr anisotropy_; + Anisotropy anisotropy_; /// Holds and classifies all inelastic factors std::shared_ptr inelastic_; diff --git a/src/mat/4C_mat_multiplicative_split_defgrad_elasthyper_service.hpp b/src/mat/4C_mat_multiplicative_split_defgrad_elasthyper_service.hpp index b4cf497f4d5..61b09d368e0 100644 --- a/src/mat/4C_mat_multiplicative_split_defgrad_elasthyper_service.hpp +++ b/src/mat/4C_mat_multiplicative_split_defgrad_elasthyper_service.hpp @@ -14,8 +14,10 @@ #include "4C_linalg_fixedsizematrix_tensor_products.hpp" #include "4C_linalg_fixedsizematrix_voigt_notation.hpp" #include "4C_linalg_symmetric_tensor.hpp" +#include "4C_linalg_tensor.hpp" #include "4C_linalg_tensor_conversion.hpp" #include "4C_linalg_tensor_generators.hpp" +#include "4C_linalg_utils_densematrix_determinant.hpp" #include "4C_mat_elasthyper_service.hpp" #include "4C_mat_service.hpp" @@ -63,37 +65,102 @@ namespace Mat Core::LinAlg::Matrix<8, 1> delta{Core::LinAlg::Initialization::zero}; }; - /// Thermal stretch quantities used by multiplicative-split thermoelastic stress evaluation. - struct ThermalQuantities + /// helper to store a second order tensor and its derivative w.r.t. temperature + struct TensorAndTemperatureDerivative { - // ----- variables of thermal quantities ----- // - /// thermal right Cauchy-Green deformation tensor \f$ \mathbf{C}_T \f$ stored as 6x1 - /// vector (stress-form!) - Core::LinAlg::Matrix<6, 1> CTV{Core::LinAlg::Initialization::zero}; - /// inverse thermal right Cauchy-Green deformation tensor \f$ \mathbf{C}_T^{-1} \f$ stored as - /// 6x1 vector (stress-form) - Core::LinAlg::Matrix<6, 1> iCTV{Core::LinAlg::Initialization::zero}; - /// \f$ \mathbf{F}_{\text{in}}^{-1} \mathbf{C}_T \mathbf{F}_{\text{in}}^{-T} \f$ stored as 6x1 - /// vector (stress-form!) - Core::LinAlg::Matrix<6, 1> iFinCTiFinTV{Core::LinAlg::Initialization::zero}; - /// \f$ \mathbf{F}_{\text{in}}^{-1} \mathbf{C}_T^{-1} \mathbf{F}_{\text{in}}^{-T} \f$ stored - /// as 6x1 vector (stress-form!) - Core::LinAlg::Matrix<6, 1> iFiniCTiFinTV{Core::LinAlg::Initialization::zero}; - /// derivative of thermal right Cauchy-Green deformation tensor wrt temperature \f$ \mathrm{d} - /// \mathbf{C}_T / \mathrm{d} T \f$ stored as 6x1 vector (strain-form!) - Core::LinAlg::Matrix<6, 1> dCTdTV{Core::LinAlg::Initialization::zero}; - - /// principal invariants of the thermal right Cauchy-Green tensor - Core::LinAlg::Matrix<3, 1> prinv{Core::LinAlg::Initialization::zero}; - - // ----- derivatives of principal invariants ----- // - - /// first derivatives of principal invariants - Core::LinAlg::Matrix<3, 1> dPI{Core::LinAlg::Initialization::zero}; - /// second derivatives of principal invariants - Core::LinAlg::Matrix<6, 1> ddPII{Core::LinAlg::Initialization::zero}; + /// value of the second order tensor + Core::LinAlg::SymmetricTensor value{}; + /// derivative of the second order tensor w.r.t. temperature + Core::LinAlg::SymmetricTensor temperature_derivative{}; }; + /// Thermal stretch quantities used by multiplicative-split thermoelastic stress evaluation. + namespace ThermalExpansion + { + + /*! + * @brief compute contribution to the thermo-elastic stress due to thermal expansion, + * \f$\boldsymbol{S}_T = S_\mathrm{he}(\boldsymbol{C}_T)\f$, and its partial derivative w.r.t. + * temperature: + * \f$\frac{\partial \mathbf{S}_T}{\partial T} = + * \frac{1}{2}\left.\mathbb{C}_\text{he}\right|_{\boldsymbol{C}_T} : \frac{\partial + * \boldsymbol{C}_T}{\partial T}\f$ + * + * @param[in] delta_temperature current absolute temperature minus reference temperature + * @param[in] expansion_coefficient isotropic thermal expansion coefficient + * @param[in] gp Gauss point + * @param[in] eleGID element global ID + * @param[in] potsumel isotropic elastic summands used to evaluate invariant derivatives + */ + inline TensorAndTemperatureDerivative compute_thermoelastic_stress_contribution( + const double delta_temperature, const double expansion_coefficient, + const std::vector>& potsumel, const int gp, + const int eleGID) + { + auto thermoelastic_stress_contribution = TensorAndTemperatureDerivative{}; + if (expansion_coefficient == 0.0) + { + // no thermal expansion, default initialized zero values are correct + return thermoelastic_stress_contribution; + } + + /// thermal right Cauchy-Green deformation tensor due to thermal expansion, + /// \f$\mathbf{C}_T = (1 + 2 \alpha_T \Delta T)\mathbf{I}\f$, and its derivative w.r.t. + /// temperature, \f$\frac{\partial \mathbf{C}_T}{\partial T} = 2 \alpha_T \mathbf{I}\f$ + const TensorAndTemperatureDerivative thermal_cauchy_green{ + .value = (1 + 2 * expansion_coefficient * delta_temperature) * + Core::LinAlg::TensorGenerators::identity, + .temperature_derivative = + 2 * expansion_coefficient * Core::LinAlg::TensorGenerators::identity}; + + // compute principal invariants of the thermal stretch + Core::LinAlg::Matrix<3, 1> prinv_of_thermal_cauchy_green{Core::LinAlg::Initialization::zero}; + Core::LinAlg::Voigt::Stresses::invariants_principal( + prinv_of_thermal_cauchy_green, make_stress_like_voigt_view(thermal_cauchy_green.value)); + + // compute derivatives of the thermal stretch principal invariants + Core::LinAlg::Matrix<3, 1> dPI{Core::LinAlg::Initialization::zero}; + Core::LinAlg::Matrix<6, 1> ddPII{Core::LinAlg::Initialization::zero}; + for (const auto& p : potsumel) // only for isotropic components + { + p->add_derivatives_principal(dPI, ddPII, prinv_of_thermal_cauchy_green, gp, eleGID); + } + + /// \f$\left.\mathbb{C}_\text{he}\right|_{\boldsymbol{C}_T}\f$ + Core::LinAlg::SymmetricTensor hyperelast_stiffness{}; + elast_hyper_add_isotropic_stress_cmat(thermoelastic_stress_contribution.value, + hyperelast_stiffness, thermal_cauchy_green.value, inv(thermal_cauchy_green.value), + prinv_of_thermal_cauchy_green, dPI, ddPII); + + thermoelastic_stress_contribution.temperature_derivative = + 0.5 * ddot(hyperelast_stiffness, thermal_cauchy_green.temperature_derivative); + + return thermoelastic_stress_contribution; + } + + /// contribution to the 2nd Piola-Kirchhoff stress due to thermal expansion, + /// \f$\det(\boldsymbol{F}_\text{in}) \boldsymbol{F}_\text{in}^{-1} \boldsymbol{S}_T + /// \boldsymbol{F}_\text{in}^{-T}\f$, and its partial derivative w.r.t. temperature, + /// \f$\det(\boldsymbol{F}_\text{in}) \boldsymbol{F}_\text{in}^{-1} \cdot \frac{\partial + /// \mathbf{S}_T}{\partial T} \cdot \boldsymbol{F}_\text{in}^{-T}\f$ + [[nodiscard]] inline TensorAndTemperatureDerivative compute_pk2_stress_contribution( + const TensorAndTemperatureDerivative& thermoelastic_stress_contribution, + const Core::LinAlg::Matrix<3, 3>& iFinM) + { + const auto iFin = make_tensor_view(iFinM); + const double detFin = 1.0 / det(iFin); + + return { + .value = detFin * assume_symmetry(dot(dot(iFin, thermoelastic_stress_contribution.value), + transpose(iFin))), + .temperature_derivative = + detFin * + assume_symmetry( + dot(dot(iFin, get_full(thermoelastic_stress_contribution.temperature_derivative)), + transpose(iFin)))}; + } + }; // namespace ThermalExpansion + inline void evaluate_ce(const Core::LinAlg::Matrix<3, 3>& F, const Core::LinAlg::Matrix<3, 3>& iFin, Core::LinAlg::Matrix<3, 3>& Ce) { @@ -192,165 +259,7 @@ namespace Mat Core::LinAlg::FourTensorOperations::add_holzapfel_product(cmat, iCinv, delta(7)); } - /*! - * @brief Subtracts the thermal contribution from the 2nd Piola-Kirchhoff stress - * - * \f[\texttt{stress} \mathrel{{-}{=}} \det(\boldsymbol{F}_\text{in}) - * \boldsymbol{F}_\text{in}^{-1} - * \boldsymbol{S}_\text{he}[\boldsymbol{C}_\text{he} = \boldsymbol{C}_T] - * \boldsymbol{F}_\text{in}^{-T}\f] - * where \f$\boldsymbol{S}_\text{he}[\boldsymbol{C}_\text{he} = \boldsymbol{C}_T]\f$ denotes - * the hyperelastic 2nd Piola-Kirchhoff stress evaluated - * at the thermal right Cauchy-Green tensor \f$\boldsymbol{C}_T\f$. - * - * @param[in] thermal_quant Thermal stretch quantities and invariants - * @param[in] thermal_stress_fact Holzapfel stress factors for the thermal stretch - * @param[in] iCinV inverse inelastic right Cauchy-Green tensor in stress-like Voigt notation - * @param[in] detFin determinant of the inelastic deformation gradient - * @param[in,out] stress 2nd Piola-Kirchhoff stress in stress-like Voigt notation to be updated by - * the thermal contribution - */ - inline void add_thermal_stress_contribution(Core::LinAlg::Matrix<6, 1>& stress, - const ThermalQuantities& thermal_quant, const StressFactors& thermal_stress_fact, - const Core::LinAlg::Matrix<6, 1>& iCinV, const double detFin) - { - const Core::LinAlg::Matrix<3, 1>& thermal_gamma = thermal_stress_fact.gamma; - - stress.update(-detFin * thermal_gamma(0), iCinV, 1.0); - stress.update(-detFin * thermal_gamma(1), thermal_quant.iFinCTiFinTV, 1.0); - stress.update(-detFin * thermal_gamma(2), thermal_quant.iFiniCTiFinTV, 1.0); - } - - - - /*! - * @brief Evaluate the partial derivative of the 2nd Piola-Kirchhoff stress wrt. temperature: - * - * \f[\frac{\partial \boldsymbol{S}}{\partial T} - * = -\det(\boldsymbol{F}_\text{in}) \boldsymbol{F}_{\text{in}}^{-1} - * \left(\frac{1}{2}\left.\mathbb{C}_\text{he}\right|_{\boldsymbol{C}_T} - * : \frac{\partial \boldsymbol{C}_T}{\partial T} \right) - * \boldsymbol{F}_{\text{in}}^{-T}\f] - * - * where \f$\left.\mathbb{C}_\text{he}\right|_{\boldsymbol{C}_T}\f$ denotes the hyperelastic - * stiffness evaluated at the thermal right Cauchy-Green tensor \f$\boldsymbol{C}_T\f$. - * - * @param[in] iFinM inverse inelastic deformation gradient - * @param[in] thermal_quant Thermal stretch quantities and temperature derivative - * @return derivative of the thermal 2nd Piola-Kirchhoff stress w.r.t. temperature - */ - inline Core::LinAlg::Matrix<6, 1> compute_partial_d_stress_d_temperature( - const Core::LinAlg::Matrix<3, 3>& iFinM, const ThermalQuantities& thermal_quant) - { - Core::LinAlg::Matrix<6, 1> thermal_stress_deriv{Core::LinAlg::Initialization::zero}; - - const Core::LinAlg::Matrix<6, 1>& dCTdTV = thermal_quant.dCTdTV; - const double detFin = 1.0 / iFinM.determinant(); - - // evaluate purely hyperelastic stiffness with the thermal right CG tensor as input - Core::LinAlg::SymmetricTensor hyperelast_stress{}; - Core::LinAlg::SymmetricTensor hyperelast_stiffness{}; - elast_hyper_add_isotropic_stress_cmat(hyperelast_stress, hyperelast_stiffness, - Core::LinAlg::make_symmetric_tensor_from_stress_like_voigt_matrix(thermal_quant.CTV), - Core::LinAlg::make_symmetric_tensor_from_stress_like_voigt_matrix(thermal_quant.iCTV), - thermal_quant.prinv, thermal_quant.dPI, thermal_quant.ddPII); - - - /// compute derivative \f$ \frac{\partial \mathbf{S}_{\theta}}{\partial T} \f$ - - Core::LinAlg::Matrix<6, 1> pStheta_pT_stress{Core::LinAlg::Initialization::zero}; - pStheta_pT_stress.multiply_nn( - 0.5, Core::LinAlg::make_stress_like_voigt_view(hyperelast_stiffness), dCTdTV, 0.0); - Core::LinAlg::Matrix<3, 3> pStheta_pT{Core::LinAlg::Initialization::zero}; - Core::LinAlg::Voigt::Stresses::vector_to_matrix(pStheta_pT_stress, pStheta_pT); - - /// compute product \f$ \mathbf{F}_{\text{in}}^{-1} \frac{\partial - /// \mathbf{S}_{\theta}}{\partial T} \mathbf{F}_{\text{in}}^{-T} \f$ - Core::LinAlg::Matrix<3, 3> iFin_pStheta_pT{Core::LinAlg::Initialization::zero}; - iFin_pStheta_pT.multiply_nn(1.0, iFinM, pStheta_pT, 0.0); - Core::LinAlg::Matrix<3, 3> iFin_pStheta_pT_iFinT{Core::LinAlg::Initialization::zero}; - iFin_pStheta_pT_iFinT.multiply_nt(1.0, iFin_pStheta_pT, iFinM, 0.0); - Core::LinAlg::Matrix<6, 1> iFin_pStheta_pT_iFinT_V{Core::LinAlg::Initialization::zero}; - Core::LinAlg::Voigt::Stresses::matrix_to_vector(iFin_pStheta_pT_iFinT, iFin_pStheta_pT_iFinT_V); - - // thermal derivative - thermal_stress_deriv.update(-detFin, iFin_pStheta_pT_iFinT_V, 0.0); - - return thermal_stress_deriv; - } - - /*! - * @brief Compute thermal stretch quantities for isotropic thermal expansion. - * - * @param[in] delta_temperature current absolute temperature minus reference temperature - * @param[in] thermal_expansion_coefficient isotropic thermal expansion coefficient - * @param[in] iFinM inverse inelastic deformation gradient - * @param[in] gp Gauss point - * @param[in] eleGID element global ID - * @param[in] potsumel isotropic elastic summands used to evaluate invariant derivatives - * @return collected thermal kinematic quantities and invariant derivatives - */ - inline ThermalQuantities evaluate_thermal_quantities(const double delta_temperature, - const double thermal_expansion_coefficient, const Core::LinAlg::Matrix<3, 3>& iFinM, - const int gp, const int eleGID, - const std::vector>& potsumel) - { - ThermalQuantities quantities{}; - - // compute the thermal stretch, along with its temperature - // derivative - Core::LinAlg::SymmetricTensor thermal_right_cg_tensor{ - Core::LinAlg::TensorGenerators::identity}; - Core::LinAlg::SymmetricTensor thermal_right_cg_temp_deriv_tensor{}; - thermal_right_cg_tensor += 2 * thermal_expansion_coefficient * delta_temperature * - Core::LinAlg::TensorGenerators::identity; - thermal_right_cg_temp_deriv_tensor += - 2 * thermal_expansion_coefficient * Core::LinAlg::TensorGenerators::identity; - - // compute inverse of the thermal stretch - Core::LinAlg::SymmetricTensor inv_thermal_right_cg_tensor = - inv(thermal_right_cg_tensor); - - // get matrices for the thermal stretch - const Core::LinAlg::Matrix<3, 3> CTM = - Core::LinAlg::make_matrix(get_full(thermal_right_cg_tensor)); - const Core::LinAlg::Matrix<3, 3> iCTM = - Core::LinAlg::make_matrix(Core::LinAlg::get_full(inv_thermal_right_cg_tensor)); - - // compute terms with iFin - Core::LinAlg::Matrix<3, 3> iFinCT{}; - iFinCT.multiply(1.0, iFinM, CTM, 0.0); - Core::LinAlg::Matrix<3, 3> iFinCTiFinT{}; - iFinCTiFinT.multiply_nt(1.0, iFinCT, iFinM, 0.0); - Core::LinAlg::Matrix<3, 3> iFiniCT{}; - iFiniCT.multiply(1.0, iFinM, iCTM, 0.0); - Core::LinAlg::Matrix<3, 3> iFiniCTiFinT{}; - iFiniCTiFinT.multiply_nt(1.0, iFiniCT, iFinM, 0.0); - - // add computed tensors to quantities in the specified form - quantities.CTV = Core::LinAlg::make_stress_like_voigt_view(thermal_right_cg_tensor); - quantities.iCTV = Core::LinAlg::make_stress_like_voigt_view(inv_thermal_right_cg_tensor); - Core::LinAlg::Voigt::Stresses::matrix_to_vector(iFinCTiFinT, quantities.iFinCTiFinTV); - Core::LinAlg::Voigt::Stresses::matrix_to_vector(iFiniCTiFinT, quantities.iFiniCTiFinTV); - quantities.dCTdTV = Core::LinAlg::make_strain_like_voigt_matrix( - thermal_right_cg_temp_deriv_tensor); // must be in strain-form for contraction afterwards! - - // compute principal invariants of the thermal stretch - Core::LinAlg::Voigt::Stresses::invariants_principal(quantities.prinv, quantities.CTV); - - // compute derivatives of the thermal stretch principal invariants - quantities.dPI.clear(); - quantities.ddPII.clear(); - for (const auto& p : potsumel) // only for isotropic components - { - p->add_derivatives_principal(quantities.dPI, quantities.ddPII, quantities.prinv, gp, eleGID); - } - - - return quantities; - } - } // namespace Mat FOUR_C_NAMESPACE_CLOSE -#endif \ No newline at end of file +#endif diff --git a/src/mat/4C_mat_so3_material.hpp b/src/mat/4C_mat_so3_material.hpp index f629de16a53..05b7f5fc3d8 100644 --- a/src/mat/4C_mat_so3_material.hpp +++ b/src/mat/4C_mat_so3_material.hpp @@ -154,12 +154,6 @@ namespace Mat double concentration, Core::LinAlg::Matrix<9, 1>& d_F_dx); //@} - /*! - * @brief Return whether material includes a varying material density - */ - virtual bool varying_density() const { return false; } - - //! @name Handling of Gauss point data /*! * @brief Check if element kinematics and material kinematics are compatible diff --git a/src/mat/4C_mat_solid_superposition.cpp b/src/mat/4C_mat_solid_superposition.cpp new file mode 100644 index 00000000000..69f3a1a7c23 --- /dev/null +++ b/src/mat/4C_mat_solid_superposition.cpp @@ -0,0 +1,190 @@ +// This file is part of 4C multiphysics licensed under the +// GNU Lesser General Public License v3.0 or later. +// +// See the LICENSE.md file in the top-level for license information. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "4C_mat_solid_superposition.hpp" + +#include "4C_comm_pack_helpers.hpp" +#include "4C_global_data.hpp" +#include "4C_mat_material_factory.hpp" +#include "4C_mat_par_bundle.hpp" +#include "4C_mat_service.hpp" +#include "4C_utils_exceptions.hpp" + +FOUR_C_NAMESPACE_OPEN + +Mat::PAR::SolidSuperposition::SolidSuperposition(const Core::Mat::PAR::Parameter::Data& matdata) + : Parameter(matdata), + density_(matdata.parameters.get("DENS")), + matids_(matdata.parameters.get>("MATIDS")) +{ +} + +std::shared_ptr Mat::PAR::SolidSuperposition::create_material() +{ + return std::make_shared(this); +} + +Mat::SolidSuperpositionType Mat::SolidSuperpositionType::instance_; + +Core::Communication::ParObject* Mat::SolidSuperpositionType::create( + Core::Communication::UnpackBuffer& buffer) +{ + auto* mat_solid_superposition = new Mat::SolidSuperposition(); + mat_solid_superposition->unpack(buffer); + + return mat_solid_superposition; +} + +Mat::SolidSuperposition::SolidSuperposition() : params_(nullptr), materials_(0) {} + +Mat::SolidSuperposition::SolidSuperposition(Mat::PAR::SolidSuperposition* params) + : params_(params), materials_(0) +{ + // create the materials from the given material ids + for (const auto& matid : params_->matids_) + { + auto mat = std::dynamic_pointer_cast(Mat::factory(matid)); + if (!mat) FOUR_C_THROW("Failed to allocate material for matid {}", matid); + + materials_.push_back(std::move(mat)); + } +} + +void Mat::SolidSuperposition::pack(Core::Communication::PackBuffer& data) const +{ + // pack type of this instance of ParObject + int type = unique_par_object_id(); + add_to_pack(data, type); + + // pack material id + int matid = -1; + if (params_ != nullptr) matid = params_->id(); // in case we are in post-process mode + add_to_pack(data, matid); + + // pack all materials + Core::Communication::PotentiallyUnusedBufferScope materials_scope{data}; + + if (params_ != nullptr) // materials are not accessible during post processing + { + for (const auto& m : materials_) m->pack(data); + } +} + +void Mat::SolidSuperposition::unpack(Core::Communication::UnpackBuffer& buffer) +{ + // make sure we have a pristine material + params_ = nullptr; + materials_.clear(); + + Core::Communication::extract_and_assert_id(buffer, unique_par_object_id()); + + // extract matid and recover params_ + int matid; + extract_from_pack(buffer, matid); + if (Global::Problem::instance()->materials() != nullptr) + { + if (Global::Problem::instance()->materials()->num() != 0) + { + const int probinst = Global::Problem::instance()->materials()->get_read_from_problem(); + Core::Mat::PAR::Parameter* mat = + Global::Problem::instance(probinst)->materials()->parameter_by_id(matid); + if (mat->type() == material_type()) + params_ = dynamic_cast(mat); + else + FOUR_C_THROW("Type of parameter material {} does not fit to calling type {}", mat->type(), + material_type()); + } + + // extract materials + Core::Communication::PotentiallyUnusedBufferScope materials_scope{buffer}; + + if (params_ != nullptr) // materials are not accessible during post processing + { + // recreate the materials from the given material ids + for (const auto& matid : params_->matids_) + { + auto mat = std::dynamic_pointer_cast(Mat::factory(matid)); + if (!mat) FOUR_C_THROW("Failed to allocate material for matid {}", matid); + + materials_.push_back(std::move(mat)); + } + + // unpack the materials + for (const auto& m : materials_) m->unpack(buffer); + } + } +} + +void Mat::SolidSuperposition::setup(int numgp, const Discret::Elements::Fibers& fibers, + const std::optional& coord_system) +{ + for (const auto& m : materials_) m->setup(numgp, fibers, coord_system); +} + +void Mat::SolidSuperposition::post_setup(const Teuchos::ParameterList& params, const int eleGID) +{ + for (const auto& m : materials_) m->post_setup(params, eleGID); +} + +void Mat::SolidSuperposition::update() +{ + for (const auto& m : materials_) m->update(); +} + +void Mat::SolidSuperposition::update(const Core::LinAlg::Tensor& defgrd, int gp, + const Teuchos::ParameterList& params, const EvaluationContext<3>& context, int eleGID) +{ + for (const auto& m : materials_) m->update(defgrd, gp, params, context, eleGID); +} + +void Mat::SolidSuperposition::evaluate(const Core::LinAlg::Tensor* defgrad, + const Core::LinAlg::SymmetricTensor& glstrain, + const Teuchos::ParameterList& params, const EvaluationContext<3>& context, + Core::LinAlg::SymmetricTensor& stress, + Core::LinAlg::SymmetricTensor& cmat, int gp, int eleGID) +{ + stress = {}; + cmat = {}; + + Core::LinAlg::SymmetricTensor s_tmp{}; + Core::LinAlg::SymmetricTensor c_tmp{}; + + // evaluate stress and material tangent for all materials + for (const auto& m : materials_) + { + s_tmp = {}; + c_tmp = {}; + + m->evaluate(defgrad, glstrain, params, context, s_tmp, c_tmp, gp, eleGID); + + // sum up the material contributions + stress += s_tmp; + cmat += c_tmp; + } +} + +void Mat::SolidSuperposition::register_output_data_names( + std::unordered_map& names_and_size) const +{ + for (const auto& m : materials_) m->register_output_data_names(names_and_size); +} + +bool Mat::SolidSuperposition::evaluate_output_data( + const std::string& name, Core::LinAlg::SerialDenseMatrix& data) const +{ + bool data_was_set = false; + for (const auto& m : materials_) + { + if (m->evaluate_output_data(name, data)) + { + data_was_set = true; + } + } + return data_was_set; +} + +FOUR_C_NAMESPACE_CLOSE \ No newline at end of file diff --git a/src/mat/4C_mat_solid_superposition.hpp b/src/mat/4C_mat_solid_superposition.hpp new file mode 100644 index 00000000000..68c6d478eda --- /dev/null +++ b/src/mat/4C_mat_solid_superposition.hpp @@ -0,0 +1,161 @@ +// This file is part of 4C multiphysics licensed under the +// GNU Lesser General Public License v3.0 or later. +// +// See the LICENSE.md file in the top-level for license information. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef FOUR_C_MAT_SOLID_SUPERPOSITION_HPP +#define FOUR_C_MAT_SOLID_SUPERPOSITION_HPP + +#include "4C_config.hpp" + +#include "4C_comm_parobjectfactory.hpp" +#include "4C_mat_so3_material.hpp" +#include "4C_material_parameter_base.hpp" + +FOUR_C_NAMESPACE_OPEN + +namespace Mat +{ + // forward declaration + class SolidSuperposition; + + namespace PAR + { + /// parameter class for the superposition material + class SolidSuperposition : public Core::Mat::PAR::Parameter + { + friend class Mat::SolidSuperposition; + + public: + /// standard constructor + explicit SolidSuperposition(const Core::Mat::PAR::Parameter::Data& matdata); + + std::shared_ptr create_material() override; + + /// @name material parameters + /// @{ + + /// density of the material + const double density_; + + /// list of the IDs of the materials to superpose + const std::vector matids_; + + /// @} + }; + } // namespace PAR + + + class SolidSuperpositionType : public Core::Communication::ParObjectType + { + public: + [[nodiscard]] std::string name() const override { return "SolidSuperpositionType"; } + + static SolidSuperpositionType& instance() { return instance_; } + + Core::Communication::ParObject* create(Core::Communication::UnpackBuffer& buffer) override; + + private: + static SolidSuperpositionType instance_; + }; + + /*! + * \brief Material that superposes multiple 3D solid materials. + * + * This material evaluates stress and consistent tangents by combining + * contributions from multiple 3D solid materials. + * + * The second Piola-Kirchhoff stress is computed as a linear sum: + * \f[ + * S = \sum_{i} S_i + * \f] + * + * and similarly the material tangent: + * \f[ + * \mathbb{C} = \sum_{i} \mathbb{C}_i + * \f] + * + * Each constituent material is evaluated independently, and their responses are accumulated. + */ + class SolidSuperposition : public So3Material + { + public: + /// constructor for an empty material object + SolidSuperposition(); + + /// constructor for the material given the material parameters + explicit SolidSuperposition(Mat::PAR::SolidSuperposition* params); + + [[nodiscard]] int unique_par_object_id() const override + { + return SolidSuperpositionType::instance().unique_par_object_id(); + } + + void pack(Core::Communication::PackBuffer& data) const override; + + void unpack(Core::Communication::UnpackBuffer& buffer) override; + + void valid_kinematics(Inpar::Solid::KinemType kinem) override + { + if (!(kinem == Inpar::Solid::KinemType::nonlinearTotLag)) + { + FOUR_C_THROW( + "Element and material kinematics are not compatible. Use nonlinear total lagrangian" + "kinematics (KINEM nonlinear) in your element definition."); + } + } + + [[nodiscard]] Core::Materials::MaterialType material_type() const override + { + return Core::Materials::m_superposition; + } + + [[nodiscard]] std::shared_ptr clone() const override + { + return std::make_shared(*this); + } + + [[nodiscard]] Core::Mat::PAR::Parameter* parameter() const override { return params_; } + + void setup(int numgp, const Discret::Elements::Fibers& fibers, + const std::optional& coord_system) override; + + void post_setup(const Teuchos::ParameterList& params, const int eleGID) override; + + void update() override; + + void update(const Core::LinAlg::Tensor& defgrd, int gp, + const Teuchos::ParameterList& params, const EvaluationContext<3>& context, + int eleGID) override; + + bool uses_extended_update() override { return true; } + + void evaluate(const Core::LinAlg::Tensor* defgrad, + const Core::LinAlg::SymmetricTensor& glstrain, + const Teuchos::ParameterList& params, const EvaluationContext<3>& context, + Core::LinAlg::SymmetricTensor& stress, + Core::LinAlg::SymmetricTensor& cmat, int gp, int eleGID) override; + + [[nodiscard]] double density() const override { return params_->density_; } + + void register_output_data_names( + std::unordered_map& names_and_size) const override; + + bool evaluate_output_data( + const std::string& name, Core::LinAlg::SerialDenseMatrix& data) const override; + + private: + /// material parameters, i.e., the density and the list of material IDs to superpose + Mat::PAR::SolidSuperposition* params_; + + /// list of the references to the materials to superpose + std::vector> materials_; + }; + +} // namespace Mat + +FOUR_C_NAMESPACE_CLOSE + +#endif \ No newline at end of file diff --git a/src/mat/4C_mat_trait_thermo_solid.hpp b/src/mat/4C_mat_trait_thermo_solid.hpp index 211d86e1e99..0cc92889422 100644 --- a/src/mat/4C_mat_trait_thermo_solid.hpp +++ b/src/mat/4C_mat_trait_thermo_solid.hpp @@ -21,7 +21,7 @@ namespace Mat { namespace Trait { - class ThermoSolid : public Thermo, public Solid, public MonolithicSolidScalarMaterial + class ThermoSolid : public Thermo, public MonolithicSolidScalarMaterial { public: /*! diff --git a/src/mat/elast/4C_mat_elast_anisoactivestress_evolution.hpp b/src/mat/elast/4C_mat_elast_anisoactivestress_evolution.hpp index 7fd7fb0ff8a..201e2f5fd82 100644 --- a/src/mat/elast/4C_mat_elast_anisoactivestress_evolution.hpp +++ b/src/mat/elast/4C_mat_elast_anisoactivestress_evolution.hpp @@ -183,9 +183,6 @@ namespace Mat std::vector>& fibervecs ///< vector of all fiber vectors ) const override; - /// Setup of patient-specific materials - void setup_aaa(const Teuchos::ParameterList& params, const int eleGID) override {} - // update internal stress variables void update() override; diff --git a/src/mat/elast/4C_mat_elast_coupSaintVenantKirchhoff.hpp b/src/mat/elast/4C_mat_elast_coupSaintVenantKirchhoff.hpp index 31ab8e139fe..484b39a81d0 100644 --- a/src/mat/elast/4C_mat_elast_coupSaintVenantKirchhoff.hpp +++ b/src/mat/elast/4C_mat_elast_coupSaintVenantKirchhoff.hpp @@ -123,14 +123,6 @@ namespace Mat return; }; - - /// a young's modulus equivalent - void add_youngs_mod(double& young, double& shear, double& bulk) override - { - young += 9. * params_->mue_ * (3. * params_->lambda_ + 2. * params_->mue_) / - (params_->lambda_ + params_->mue_); - }; - private: /// my material parameters Mat::Elastic::PAR::CoupSVK* params_; diff --git a/src/mat/elast/4C_mat_elast_coupanisoexposhear.cpp b/src/mat/elast/4C_mat_elast_coupanisoexposhear.cpp index ed51136e522..479b2ff4ab0 100644 --- a/src/mat/elast/4C_mat_elast_coupanisoexposhear.cpp +++ b/src/mat/elast/4C_mat_elast_coupanisoexposhear.cpp @@ -69,12 +69,14 @@ Mat::Elastic::CoupAnisoExpoShearAnisotropyExtension::get_structural_tensor(int g return structural_tensors_[gp]; } -void Mat::Elastic::CoupAnisoExpoShearAnisotropyExtension::on_global_data_initialized() +void Mat::Elastic::CoupAnisoExpoShearAnisotropyExtension::on_global_data_initialized( + Mat::Anisotropy& anisotropy) { - // do nothing + (void)anisotropy; } -void Mat::Elastic::CoupAnisoExpoShearAnisotropyExtension::on_global_element_data_initialized() +void Mat::Elastic::CoupAnisoExpoShearAnisotropyExtension::on_global_element_data_initialized( + Mat::Anisotropy& anisotropy) { if (init_mode_ == DefaultAnisotropyExtension<2>::INIT_MODE_NODAL_EXTERNAL || init_mode_ == DefaultAnisotropyExtension<2>::INIT_MODE_NODAL_FIBERS) @@ -92,19 +94,18 @@ void Mat::Elastic::CoupAnisoExpoShearAnisotropyExtension::on_global_element_data DefaultAnisotropyExtension<2>::INIT_MODE_NODAL_FIBERS); } - if (get_anisotropy()->get_element_fibers().empty()) + if (anisotropy.get_element_fibers().empty()) { FOUR_C_THROW("No element fibers are given with the FIBER1 FIBER2 notation"); } scalar_products_.resize(1); structural_tensors_.resize(1); - scalar_products_[0] = get_anisotropy()->get_element_fiber(fiber_ids_[0]) * - get_anisotropy()->get_element_fiber(fiber_ids_[1]); + scalar_products_[0] = + anisotropy.get_element_fiber(fiber_ids_[0]) * anisotropy.get_element_fiber(fiber_ids_[1]); - Core::LinAlg::Tensor fiber1fiber2T = - Core::LinAlg::dyadic(get_anisotropy()->get_element_fiber(fiber_ids_[0]), - get_anisotropy()->get_element_fiber(fiber_ids_[1])); + Core::LinAlg::Tensor fiber1fiber2T = Core::LinAlg::dyadic( + anisotropy.get_element_fiber(fiber_ids_[0]), anisotropy.get_element_fiber(fiber_ids_[1])); structural_tensors_[0] = 0.5 * Core::LinAlg::assume_symmetry(fiber1fiber2T + Core::LinAlg::transpose(fiber1fiber2T)); @@ -112,7 +113,8 @@ void Mat::Elastic::CoupAnisoExpoShearAnisotropyExtension::on_global_element_data is_initialized_ = true; } -void Mat::Elastic::CoupAnisoExpoShearAnisotropyExtension::on_global_gp_data_initialized() +void Mat::Elastic::CoupAnisoExpoShearAnisotropyExtension::on_global_gp_data_initialized( + Mat::Anisotropy& anisotropy) { if (init_mode_ == DefaultAnisotropyExtension<2>::INIT_MODE_ELEMENT_EXTERNAL || init_mode_ == DefaultAnisotropyExtension<2>::INIT_MODE_ELEMENT_FIBERS) @@ -130,22 +132,22 @@ void Mat::Elastic::CoupAnisoExpoShearAnisotropyExtension::on_global_gp_data_init DefaultAnisotropyExtension<2>::INIT_MODE_NODAL_FIBERS); } - if (get_anisotropy()->get_number_of_gauss_point_fibers() == 0) + if (anisotropy.get_number_of_gauss_point_fibers() == 0) { - FOUR_C_THROW("No element fibers are given with the FIBER1 FIBER2 notation"); + FOUR_C_THROW("No Gauss-point fibers are given with the FIBER1 FIBER2 notation"); } - scalar_products_.resize(get_anisotropy()->get_number_of_gauss_points()); - structural_tensors_.resize(get_anisotropy()->get_number_of_gauss_points()); + scalar_products_.resize(anisotropy.get_number_of_gauss_points()); + structural_tensors_.resize(anisotropy.get_number_of_gauss_points()); - for (auto gp = 0; gp < get_anisotropy()->get_number_of_gauss_points(); ++gp) + for (auto gp = 0; gp < anisotropy.get_number_of_gauss_points(); ++gp) { - scalar_products_[gp] = get_anisotropy()->get_gauss_point_fiber(gp, fiber_ids_[0]) * - get_anisotropy()->get_gauss_point_fiber(gp, fiber_ids_[1]); + scalar_products_[gp] = anisotropy.get_gauss_point_fiber(gp, fiber_ids_[0]) * + anisotropy.get_gauss_point_fiber(gp, fiber_ids_[1]); Core::LinAlg::Tensor fiber1fiber2T = - Core::LinAlg::dyadic(get_anisotropy()->get_gauss_point_fiber(gp, fiber_ids_[0]), - get_anisotropy()->get_gauss_point_fiber(gp, fiber_ids_[1])); + Core::LinAlg::dyadic(anisotropy.get_gauss_point_fiber(gp, fiber_ids_[0]), + anisotropy.get_gauss_point_fiber(gp, fiber_ids_[1])); structural_tensors_[gp] = 0.5 * Core::LinAlg::assume_symmetry(fiber1fiber2T + Core::LinAlg::transpose(fiber1fiber2T)); diff --git a/src/mat/elast/4C_mat_elast_coupanisoexposhear.hpp b/src/mat/elast/4C_mat_elast_coupanisoexposhear.hpp index c77a8ce6e26..1a6ef72026b 100644 --- a/src/mat/elast/4C_mat_elast_coupanisoexposhear.hpp +++ b/src/mat/elast/4C_mat_elast_coupanisoexposhear.hpp @@ -55,11 +55,11 @@ namespace Mat * * The coupling structural tensor and the scalar product will be computed here */ - void on_global_data_initialized() override; + void on_global_data_initialized(Anisotropy& anisotropy) override; protected: - void on_global_element_data_initialized() override; - void on_global_gp_data_initialized() override; + void on_global_element_data_initialized(Anisotropy& anisotropy) override; + void on_global_gp_data_initialized(Anisotropy& anisotropy) override; private: /** diff --git a/src/mat/elast/4C_mat_elast_coupanisoneohooke_VarProp.hpp b/src/mat/elast/4C_mat_elast_coupanisoneohooke_VarProp.hpp index e9e286bb660..8d955c53a40 100644 --- a/src/mat/elast/4C_mat_elast_coupanisoneohooke_VarProp.hpp +++ b/src/mat/elast/4C_mat_elast_coupanisoneohooke_VarProp.hpp @@ -138,9 +138,6 @@ namespace Mat std::vector>& fibervecs ///< vector of all fiber vectors ) const override; - /// Setup of patient-specific materials - void setup_aaa(const Teuchos::ParameterList& params, const int eleGID) override { return; } - /// Indicator for formulation void specify_formulation( bool& isoprinc, ///< global indicator for isotropic principal formulation diff --git a/src/mat/elast/4C_mat_elast_coupblatzko.hpp b/src/mat/elast/4C_mat_elast_coupblatzko.hpp index c756c36af4f..cb41dcaa162 100644 --- a/src/mat/elast/4C_mat_elast_coupblatzko.hpp +++ b/src/mat/elast/4C_mat_elast_coupblatzko.hpp @@ -125,12 +125,6 @@ namespace Mat void add_coup_deriv_vol( const double j, double* dPj1, double* dPj2, double* dPj3, double* dPj4) override; - /// add young's modulus equivalent - void add_youngs_mod(double& young, double& shear, double& bulk) override - { - young += 2. * mue() * (1. + nue()); - }; - /// @name Access methods //@{ double mue() const { return params_->mue_; } diff --git a/src/mat/elast/4C_mat_elast_couplogmixneohooke.cpp b/src/mat/elast/4C_mat_elast_couplogmixneohooke.cpp index 77afcbf4c11..cfd9adc38c6 100644 --- a/src/mat/elast/4C_mat_elast_couplogmixneohooke.cpp +++ b/src/mat/elast/4C_mat_elast_couplogmixneohooke.cpp @@ -46,17 +46,6 @@ Mat::Elastic::CoupLogMixNeoHooke::CoupLogMixNeoHooke(Mat::Elastic::PAR::CoupLogM { } -void Mat::Elastic::CoupLogMixNeoHooke::add_shear_mod( - bool& haveshearmod, ///< non-zero shear modulus was added - double& shearmod, ///< variable to add upon - int ele_gid ///< element GID -) const -{ - haveshearmod = true; - - shearmod += params_->mue_; -} - void Mat::Elastic::CoupLogMixNeoHooke::add_strain_energy(double& psi, const Core::LinAlg::Matrix<3, 1>& prinv, const Core::LinAlg::Matrix<3, 1>& modinv, const Core::LinAlg::SymmetricTensor& glstrain, const int gp, const int eleGID) diff --git a/src/mat/elast/4C_mat_elast_couplogmixneohooke.hpp b/src/mat/elast/4C_mat_elast_couplogmixneohooke.hpp index fd87f54b4ce..3f9c4cc8f39 100644 --- a/src/mat/elast/4C_mat_elast_couplogmixneohooke.hpp +++ b/src/mat/elast/4C_mat_elast_couplogmixneohooke.hpp @@ -81,12 +81,15 @@ namespace Mat { return Core::Materials::mes_couplogmixneohooke; } - /// add shear modulus equivalent void add_shear_mod(bool& haveshearmod, ///< non-zero shear modulus was added double& shearmod, ///< variable to add upon int ele_gid ///< element GID - ) const override; + ) const override + { + haveshearmod = true; + shearmod += params_->mue_; + }; //@} diff --git a/src/mat/elast/4C_mat_elast_couplogneohooke.cpp b/src/mat/elast/4C_mat_elast_couplogneohooke.cpp index f4d623fa311..95fcd97a6c2 100644 --- a/src/mat/elast/4C_mat_elast_couplogneohooke.cpp +++ b/src/mat/elast/4C_mat_elast_couplogneohooke.cpp @@ -45,17 +45,6 @@ Mat::Elastic::CoupLogNeoHooke::CoupLogNeoHooke(Mat::Elastic::PAR::CoupLogNeoHook { } -void Mat::Elastic::CoupLogNeoHooke::add_shear_mod( - bool& haveshearmod, ///< non-zero shear modulus was added - double& shearmod, ///< variable to add upon - int ele_gid ///< element GID -) const -{ - haveshearmod = true; - - shearmod += params_->mue_; -} - void Mat::Elastic::CoupLogNeoHooke::add_strain_energy(double& psi, const Core::LinAlg::Matrix<3, 1>& prinv, const Core::LinAlg::Matrix<3, 1>& modinv, const Core::LinAlg::SymmetricTensor& glstrain, const int gp, const int eleGID) diff --git a/src/mat/elast/4C_mat_elast_couplogneohooke.hpp b/src/mat/elast/4C_mat_elast_couplogneohooke.hpp index 61239d8863d..49cadd859e3 100644 --- a/src/mat/elast/4C_mat_elast_couplogneohooke.hpp +++ b/src/mat/elast/4C_mat_elast_couplogneohooke.hpp @@ -97,7 +97,11 @@ namespace Mat void add_shear_mod(bool& haveshearmod, ///< non-zero shear modulus was added double& shearmod, ///< variable to add upon int ele_gid ///< element GID - ) const override; + ) const override + { + haveshearmod = true; + shearmod += params_->mue_; + }; //@} diff --git a/src/mat/elast/4C_mat_elast_coupneohooke.cpp b/src/mat/elast/4C_mat_elast_coupneohooke.cpp index 9c7d0a27a65..29e9fd232fd 100644 --- a/src/mat/elast/4C_mat_elast_coupneohooke.cpp +++ b/src/mat/elast/4C_mat_elast_coupneohooke.cpp @@ -28,17 +28,6 @@ Mat::Elastic::CoupNeoHooke::CoupNeoHooke(Mat::Elastic::PAR::CoupNeoHooke* params { } -void Mat::Elastic::CoupNeoHooke::add_shear_mod( - bool& haveshearmod, ///< non-zero shear modulus was added - double& shearmod, ///< variable to add upon - int ele_gid ///< element GID -) const -{ - haveshearmod = true; - - shearmod += 2 * params_->c_; -} - void Mat::Elastic::CoupNeoHooke::add_strain_energy(double& psi, const Core::LinAlg::Matrix<3, 1>& prinv, const Core::LinAlg::Matrix<3, 1>& modinv, const Core::LinAlg::SymmetricTensor& glstrain, const int gp, const int eleGID) diff --git a/src/mat/elast/4C_mat_elast_coupneohooke.hpp b/src/mat/elast/4C_mat_elast_coupneohooke.hpp index a7d2ede3d0c..84a36ac4a51 100644 --- a/src/mat/elast/4C_mat_elast_coupneohooke.hpp +++ b/src/mat/elast/4C_mat_elast_coupneohooke.hpp @@ -106,12 +106,10 @@ namespace Mat void add_shear_mod(bool& haveshearmod, ///< non-zero shear modulus was added double& shearmod, ///< variable to add upon int ele_gid ///< element GID - ) const override; - - /// add young's modulus equivalent - void add_youngs_mod(double& young, double& shear, double& bulk) override + ) const override { - young += youngs(); + haveshearmod = true; + shearmod += 2 * params_->c_; }; //@} diff --git a/src/mat/elast/4C_mat_elast_coupvarga.cpp b/src/mat/elast/4C_mat_elast_coupvarga.cpp index 61f4c28d0df..0444f133b84 100644 --- a/src/mat/elast/4C_mat_elast_coupvarga.cpp +++ b/src/mat/elast/4C_mat_elast_coupvarga.cpp @@ -21,19 +21,6 @@ Mat::Elastic::PAR::CoupVarga::CoupVarga(const Core::Mat::PAR::Parameter::Data& m Mat::Elastic::CoupVarga::CoupVarga(Mat::Elastic::PAR::CoupVarga* params) : params_(params) {} -void Mat::Elastic::CoupVarga::add_shear_mod( - bool& haveshearmod, ///< non-zero shear modulus was added - double& shearmod, ///< variable to add upon - int ele_gid ///< element GID -) const -{ - // indeed, a shear modulus is provided - haveshearmod = haveshearmod or true; - - // material parameters for isochoric part - shearmod += params_->mue_; -} - void Mat::Elastic::CoupVarga::add_coefficients_stretches_principal( Core::LinAlg::Matrix<3, 1>& gamma, ///< see above, [gamma_1, gamma_2, gamma_3] Core::LinAlg::Matrix<6, 1>& diff --git a/src/mat/elast/4C_mat_elast_coupvarga.hpp b/src/mat/elast/4C_mat_elast_coupvarga.hpp index dd76f8b334d..1fbc15fea44 100644 --- a/src/mat/elast/4C_mat_elast_coupvarga.hpp +++ b/src/mat/elast/4C_mat_elast_coupvarga.hpp @@ -98,7 +98,14 @@ namespace Mat void add_shear_mod(bool& haveshearmod, ///< non-zero shear modulus was added double& shearmod, ///< variable to add upon int ele_gid ///< element GID - ) const override; + ) const override + { + // indeed, a shear modulus is provided + haveshearmod = true; + + // material parameters for isochoric part + shearmod += params_->mue_; + }; //@} diff --git a/src/mat/elast/4C_mat_elast_isoneohooke.cpp b/src/mat/elast/4C_mat_elast_isoneohooke.cpp index a88a1bbe215..b12d20e3979 100644 --- a/src/mat/elast/4C_mat_elast_isoneohooke.cpp +++ b/src/mat/elast/4C_mat_elast_isoneohooke.cpp @@ -19,14 +19,6 @@ Mat::Elastic::PAR::IsoNeoHooke::IsoNeoHooke(const Core::Mat::PAR::Parameter::Dat Mat::Elastic::IsoNeoHooke::IsoNeoHooke(Mat::Elastic::PAR::IsoNeoHooke* params) : params_(params) {} -void Mat::Elastic::IsoNeoHooke::add_shear_mod( - bool& haveshearmod, double& shearmod, int ele_gid) const -{ - haveshearmod = haveshearmod or true; - - shearmod += params_->mue_.at(ele_gid); -} - void Mat::Elastic::IsoNeoHooke::add_strain_energy(double& psi, const Core::LinAlg::Matrix<3, 1>& prinv, const Core::LinAlg::Matrix<3, 1>& modinv, const Core::LinAlg::SymmetricTensor& glstrain, const int gp, const int eleGID) diff --git a/src/mat/elast/4C_mat_elast_isoneohooke.hpp b/src/mat/elast/4C_mat_elast_isoneohooke.hpp index b92a84a98fe..7157e4b002e 100644 --- a/src/mat/elast/4C_mat_elast_isoneohooke.hpp +++ b/src/mat/elast/4C_mat_elast_isoneohooke.hpp @@ -82,13 +82,17 @@ namespace Mat Core::Materials::MaterialType material_type() const override { return Core::Materials::mes_isoneohooke; - } + }; /// add shear modulus equivalent void add_shear_mod(bool& haveshearmod, ///< non-zero shear modulus was added double& shearmod, ///< variable to add upon int ele_gid ///< element GID - ) const override; + ) const override + { + haveshearmod = true; + shearmod += params_->mue_.at(ele_gid); + }; //@} diff --git a/src/mat/elast/4C_mat_elast_isovarga.cpp b/src/mat/elast/4C_mat_elast_isovarga.cpp index 61d216c0d5e..28cbbc9fd40 100644 --- a/src/mat/elast/4C_mat_elast_isovarga.cpp +++ b/src/mat/elast/4C_mat_elast_isovarga.cpp @@ -20,15 +20,6 @@ Mat::Elastic::PAR::IsoVarga::IsoVarga(const Core::Mat::PAR::Parameter::Data& mat Mat::Elastic::IsoVarga::IsoVarga(Mat::Elastic::PAR::IsoVarga* params) : params_(params) {} -void Mat::Elastic::IsoVarga::add_shear_mod(bool& haveshearmod, double& shearmod, int ele_gid) const -{ - // indeed, a shear modulus is provided - haveshearmod = haveshearmod or true; - - // material parameters for isochoric part - shearmod += params_->mue_; -} - void Mat::Elastic::IsoVarga::add_coefficients_stretches_modified( Core::LinAlg::Matrix<3, 1>& modgamma, Core::LinAlg::Matrix<6, 1>& moddelta, const Core::LinAlg::Matrix<3, 1>& modstr) diff --git a/src/mat/elast/4C_mat_elast_isovarga.hpp b/src/mat/elast/4C_mat_elast_isovarga.hpp index 6eed3a83eef..c0b9251f9f7 100644 --- a/src/mat/elast/4C_mat_elast_isovarga.hpp +++ b/src/mat/elast/4C_mat_elast_isovarga.hpp @@ -99,7 +99,14 @@ namespace Mat void add_shear_mod(bool& haveshearmod, ///< non-zero shear modulus was added double& shearmod, ///< variable to add upon int ele_gid ///< element GID - ) const override; + ) const override + { + // indeed, a shear modulus is provided + haveshearmod = true; + + // material parameters for isochoric part + shearmod += params_->mue_; + }; //@} diff --git a/src/mat/elast/4C_mat_elast_summand.cpp b/src/mat/elast/4C_mat_elast_summand.cpp index 47247641623..4356ea9bf71 100644 --- a/src/mat/elast/4C_mat_elast_summand.cpp +++ b/src/mat/elast/4C_mat_elast_summand.cpp @@ -266,16 +266,11 @@ std::shared_ptr Mat::Elastic::Summand::factory(int matnum return nullptr; } -void Mat::Elastic::Summand::add_shear_mod(bool& haveshearmod, double& shearmod, int ele_gid) const -{ - FOUR_C_THROW("Mat::Elastic::Summand::AddShearMod: Add Shear Modulus not implemented - do so!"); -} - int Mat::Elastic::Summand::unique_par_object_id() const { return -1; } -void Mat::Elastic::Summand::pack(Core::Communication::PackBuffer& data) const { return; } +void Mat::Elastic::Summand::pack(Core::Communication::PackBuffer& data) const {} -void Mat::Elastic::Summand::unpack(Core::Communication::UnpackBuffer& buffer) { return; }; +void Mat::Elastic::Summand::unpack(Core::Communication::UnpackBuffer& buffer) {}; // Function which reads in the given fiber value due to the CIR-AXI-RAD nomenclature void Mat::Elastic::Summand::read_rad_axi_cir( diff --git a/src/mat/elast/4C_mat_elast_summand.hpp b/src/mat/elast/4C_mat_elast_summand.hpp index 8e106bc5eac..f9d882e99c9 100644 --- a/src/mat/elast/4C_mat_elast_summand.hpp +++ b/src/mat/elast/4C_mat_elast_summand.hpp @@ -113,9 +113,6 @@ namespace Mat virtual void setup(int numgp, const Discret::Elements::Fibers& fibers, const std::optional& coord_system) {}; - //! Dummy routine for setup of patient-specific materials - virtual void setup_aaa(const Teuchos::ParameterList& params, const int eleGID) {}; - /*! * @brief Post setup routine for summands. It will be called once after everything is set up. * @@ -145,12 +142,11 @@ namespace Mat virtual void add_shear_mod(bool& haveshearmod, ///< non-zero shear modulus was added double& shearmod, ///< variable to add upon int ele_gid ///< element GID - ) const; - - //! add young's modulus equivalent - virtual void add_youngs_mod(double& young, double& shear, double& bulk) + ) const { - FOUR_C_THROW("Summand does not support calculation of youngs modulus"); + FOUR_C_THROW( + "Mat::Elastic::Summand does not implement the calculation of shear modulus. Needs to " + "be implemented in derived class."); }; /*! diff --git a/src/mat/vplast/4C_mat_vplast_law.cpp b/src/mat/vplast/4C_mat_vplast_law.cpp index 46214201b60..40ba5e76b98 100644 --- a/src/mat/vplast/4C_mat_vplast_law.cpp +++ b/src/mat/vplast/4C_mat_vplast_law.cpp @@ -19,15 +19,22 @@ FOUR_C_NAMESPACE_OPEN /*--------------------------------------------------------------------* *--------------------------------------------------------------------*/ -Mat::Viscoplastic::Law::Law(Core::Mat::PAR::Parameter* params) : params_(params) {} +Mat::Viscoplastic::Law::Law(Core::Mat::PAR::Parameter* params, + const InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorRegistrationSettings + error_registration_settings) + : error_registration_settings_(error_registration_settings), params_(params) +{ +} /*--------------------------------------------------------------------* *--------------------------------------------------------------------*/ -Mat::Viscoplastic::Law::Law() : params_(nullptr) {} +Mat::Viscoplastic::Law::Law() : error_registration_settings_(), params_(nullptr) {} /*--------------------------------------------------------------------* *--------------------------------------------------------------------*/ -std::shared_ptr Mat::Viscoplastic::Law::factory(int matnum) +std::shared_ptr Mat::Viscoplastic::Law::factory(int matnum, + const InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorRegistrationSettings + error_registration_settings) { // for the sake of safety if (Global::Problem::instance()->materials() == nullptr) @@ -53,7 +60,8 @@ std::shared_ptr Mat::Viscoplastic::Law::factory(int matn auto* params = dynamic_cast(curmat); // return pointer to material - return std::make_shared(params); + return std::make_shared( + params, error_registration_settings); } default: diff --git a/src/mat/vplast/4C_mat_vplast_law.hpp b/src/mat/vplast/4C_mat_vplast_law.hpp index 2519c2058c4..22dda9ff668 100644 --- a/src/mat/vplast/4C_mat_vplast_law.hpp +++ b/src/mat/vplast/4C_mat_vplast_law.hpp @@ -61,8 +61,10 @@ namespace Mat class Law { public: - /// construct viscoplastic laws with specific material params - explicit Law(Core::Mat::PAR::Parameter* params); + /// construct viscoplastic laws with specific material params and error registration settings + explicit Law(Core::Mat::PAR::Parameter* params, + const InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorRegistrationSettings + error_registration_settings); /// construct empty viscoplastic law Law(); @@ -73,12 +75,20 @@ namespace Mat * @brief create object by input parameter ID * * @param[in] matnum material ID + * @param[in] error_registration_settings error registration settings for plastic strain + * increments and derivative increments * @return pointer to material that is defined by material ID */ - static std::shared_ptr factory(int matnum); + static std::shared_ptr factory(int matnum, + const InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorRegistrationSettings + error_registration_settings); /// provide material type - virtual Core::Materials::MaterialType material_type() const = 0; + [[nodiscard]] virtual Core::Materials::MaterialType material_type() const = 0; + + /// does the viscoplastic law use a yield surface formulation, or is it a no-yield-surface + /// law? + [[nodiscard]] virtual bool uses_yield_surface() const = 0; /*! * @brief Evaluate the ratio of the equivalent stress \f$ \overline{\sigma} \f$ to the yield @@ -117,7 +127,7 @@ namespace Mat * * @note To use the viscoplasticity components in the time * integration of history variables within InelasticDefgradTransvIsotropElastViscoplast, we - * have to check for eventual overflow errors within them. Specifically, we focus on the term + * may check for eventual overflow errors within them. Specifically, we focus on the term * \f$ \Delta t \dot{\varepsilon}^{\text{p}} \f$, which shall be * evaluable in the specific time integration used. Moreover, * for some viscoplasticity laws, we have to make sure that the given plastic strain is \f$ @@ -128,15 +138,11 @@ namespace Mat * @param[in] equiv_stress Equivalent stress \f$ \overline{\sigma} \f$ * @param[in] equiv_plastic_strain Equivalent plastic strain \f$ \varepsilon^{\text{p}}\f$ * @param[in] dt Time step size (used solely for overflow error checking, see @note) - * @param[in] max_plastic_strain_incr maximum, numerically evaluable plastic - * strain increment \f$ \Delta t \dot{\varepsilon}^{\text{p}}) \f$ (before throwing an - * overflow error) - * @param[out] err_status output variable: error of the terms considered in - * @note? + * @param[out] err_status Output variable: error due the term considered in @note? * @return Equivalent plastic strain rate \f$ \dot{\varepsilon}^{\text{p}} \f$ */ virtual double evaluate_plastic_strain_rate(const double equiv_stress, - const double equiv_plastic_strain, const double dt, const double max_plastic_strain_incr, + const double equiv_plastic_strain, const double dt, Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status, const bool update_hist_var = true) = 0; @@ -145,28 +151,27 @@ namespace Mat * \dot{\varepsilon}^{\text{p}} \f$ for a given equivalent stress \f$ \overline{\sigma} \f$ * and a given plastic strain \f$ \varepsilon^{\text{p}} \f$ * + * @note In addition to checking overflow based on the plastic strain increment (see + * documentation of evaluate_plastic_strain_rate), we may also verify overflow based on the + * derivatives of the plastic strain rate, scaled by the considered timestep. + * + * * @param[in] equiv_stress Equivalent stress \f$ \overline{\sigma} \f$ * @param[in] equiv_plastic_strain Equivalent plastic strain \f$ \varepsilon^{\text{p}}\f$ * @param[in] dt Time step size (used solely for overflow error checking, see @note of * evaluate_plastic_strain_rate) - * @param[in] max_plastic_strain_deriv_incr Maximum - * numerically evaluable increment of the - * plastic strain derivatives (before throwing an overflow error), - * i.e. \f$ \Delta t \frac{\partial \dot{\varepsilon}^{\text{p}}}{\partial s},~ s \in - * \{\varepsilon^{\text{p}}, \overline{\sigma}, T\} \f$ - * @param[out] err_status output variable: error of the terms considered in @note? + * @param[out] err_status Output variable: error of the terms considered in @note? * @return Derivatives of the equivalent plastic strain rate w.r.t. the equivalent stress, * plastic strain, and temperature. */ virtual InelasticDefgradTransvIsotropElastViscoplastUtils::PlasticStrainRateDerivs evaluate_derivatives_of_plastic_strain_rate(const double equiv_stress, const double equiv_plastic_strain, const double dt, - const double max_plastic_strain_deriv_incr, Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status, const bool update_hist_var = true) = 0; /// Return material parameters - virtual Core::Mat::PAR::Parameter* parameter() const { return params_; } + [[nodiscard]] virtual Core::Mat::PAR::Parameter* parameter() const { return params_; } /*! * @brief Setup viscoplasticity law for the specific element @@ -187,9 +192,12 @@ namespace Mat virtual void pre_evaluate(const Teuchos::ParameterList& params, int gp) { gp_ = gp; }; /*! - * @brief Update history variables of the viscoplasticity law for next time step + * @brief Update history variables of the viscoplasticity law for next time step at a given + * Gauss point + * + * @param[in] gp Current Gauss point */ - virtual void update() = 0; + virtual void update(const unsigned int gp) = 0; /*! * @brief Update the history variables for a specific GP after a converged substep @@ -197,7 +205,7 @@ namespace Mat * * @param[in] gp Gauss point */ - virtual void update_gp_state(int gp) = 0; + virtual void update_gp_state_after_substep(const unsigned int gp) = 0; virtual void pack_viscoplastic_law(Core::Communication::PackBuffer& data) const = 0; @@ -234,6 +242,11 @@ namespace Mat /// Gauss point index int gp_; + /// error registration settings for the plastic strain increments and the derivative + /// increments + const Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorRegistrationSettings + error_registration_settings_; + private: /// material parameters diff --git a/src/mat/vplast/4C_mat_vplast_reform_johnsoncook.cpp b/src/mat/vplast/4C_mat_vplast_reform_johnsoncook.cpp index d86f8b37f55..f49badcfc86 100644 --- a/src/mat/vplast/4C_mat_vplast_reform_johnsoncook.cpp +++ b/src/mat/vplast/4C_mat_vplast_reform_johnsoncook.cpp @@ -49,8 +49,10 @@ Mat::Viscoplastic::PAR::ReformulatedJohnsonCook::ReformulatedJohnsonCook( /*--------------------------------------------------------------------* *--------------------------------------------------------------------*/ Mat::Viscoplastic::ReformulatedJohnsonCook::ReformulatedJohnsonCook( - Core::Mat::PAR::Parameter* params) - : Mat::Viscoplastic::Law(params), + Core::Mat::PAR::Parameter* params, + const InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorRegistrationSettings + error_registration_settings) + : Mat::Viscoplastic::Law(params, error_registration_settings), const_pars_(parameter()->strain_rate_pre_fac(), 1.0 / parameter()->strain_rate_exp_fac(), parameter()->isotrop_harden_prefac(), parameter()->isotrop_harden_exp(), parameter()->init_yield_strength()) @@ -138,8 +140,7 @@ double Mat::Viscoplastic::ReformulatedJohnsonCook::compute_flow_resistance( *--------------------------------------------------------------------*/ double Mat::Viscoplastic::ReformulatedJohnsonCook::evaluate_plastic_strain_rate( const double equiv_stress, const double equiv_plastic_strain, const double dt, - const double max_plastic_strain_incr, ViscoplastErrorType& err_status, - const bool update_hist_var) + ViscoplastErrorType& err_status, const bool update_hist_var) { // first set error status to "no errors" err_status = ViscoplastErrorType::no_errors; @@ -176,10 +177,6 @@ double Mat::Viscoplastic::ReformulatedJohnsonCook::evaluate_plastic_strain_rate( EnumTools::enum_name(yield_strength_err_status)); } - // verify whether the maximum plastic strain increment is larger than 0, since we will take its - // logarithm - FOUR_C_ASSERT_ALWAYS(max_plastic_strain_incr > 0.0, - "Maximum plastic strain increment must be > 0: current value = {}", max_plastic_strain_incr); // stress ratio double stress_ratio = evaluate_stress_ratio(equiv_stress, equiv_plastic_strain); @@ -193,7 +190,9 @@ double Mat::Viscoplastic::ReformulatedJohnsonCook::evaluate_plastic_strain_rate( // check if characteristic term too large, throw error overflow // error if so - if (std::log(dt) + log_temp > std::log(max_plastic_strain_incr + const_pars_.p * dt)) + if (error_registration_settings_.register_plastic_strain_incr_overflow && + (std::log(dt) + log_temp > + std::log(error_registration_settings_.max_plastic_strain_incr + const_pars_.p * dt))) { err_status = ViscoplastErrorType::overflow_error; return -1; @@ -210,8 +209,7 @@ double Mat::Viscoplastic::ReformulatedJohnsonCook::evaluate_plastic_strain_rate( Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::PlasticStrainRateDerivs Mat::Viscoplastic::ReformulatedJohnsonCook::evaluate_derivatives_of_plastic_strain_rate( const double equiv_stress, const double equiv_plastic_strain, const double dt, - const double max_plastic_strain_deriv_incr, ViscoplastErrorType& err_status, - const bool update_hist_var) + ViscoplastErrorType& err_status, const bool update_hist_var) { // declare derivatives to be computed double deriv_equiv_stress{0.0}; @@ -279,19 +277,15 @@ Mat::Viscoplastic::ReformulatedJohnsonCook::evaluate_derivatives_of_plastic_stra const_pars_.log_p_e + const_pars_.e * (equiv_stress * inv_yield_strength - 1.0) + log_equiv_stress - 2.0 * log_yield_strength + log_neg_d_yield_strength_d_temperature; - // verify whether the maximum plastic strain derivative increment is larger than 0, since we - // will take its logarithm - FOUR_C_ASSERT_ALWAYS(max_plastic_strain_deriv_incr > 0.0, - "Maximum plastic strain derivative increment must be > 0: current value = {}", - max_plastic_strain_deriv_incr); - // perfect plasticity if (const_pars_.is_perfect_plasticity) { // check overflow error using these logarithms - double log_max_plastic_strain_deriv_value = std::log(max_plastic_strain_deriv_incr); - if ((log_dt + log_deriv_sigma > log_max_plastic_strain_deriv_value) or - (log_dt + log_deriv_temperature > log_max_plastic_strain_deriv_value)) + double log_max_plastic_strain_deriv_value = + std::log(error_registration_settings_.max_plastic_strain_deriv_incr); + if (error_registration_settings_.register_plastic_strain_deriv_incr_overflow && + ((log_dt + log_deriv_sigma > log_max_plastic_strain_deriv_value) or + (log_dt + log_deriv_temperature > log_max_plastic_strain_deriv_value))) { err_status = ViscoplastErrorType::failed_computation_flow_resistance_derivs; return InelasticDefgradTransvIsotropElastViscoplastUtils::PlasticStrainRateDerivs{ @@ -311,10 +305,12 @@ Mat::Viscoplastic::ReformulatedJohnsonCook::evaluate_derivatives_of_plastic_stra log_equiv_stress - 2.0 * log_yield_strength + const_pars_.log_B_N + (const_pars_.N - 1.0) * log_equiv_plastic_strain + log_temperature_ratio_; // check overflow error using these logarithms - double log_max_plastic_strain_deriv_value = std::log(max_plastic_strain_deriv_incr); - if ((log_dt + log_deriv_sigma > log_max_plastic_strain_deriv_value) or - (log_dt + log_neg_deriv_eps > log_max_plastic_strain_deriv_value) or - (log_dt + log_deriv_temperature > log_max_plastic_strain_deriv_value)) + double log_max_plastic_strain_deriv_value = + std::log(error_registration_settings_.max_plastic_strain_deriv_incr); + if (error_registration_settings_.register_plastic_strain_deriv_incr_overflow && + ((log_dt + log_deriv_sigma > log_max_plastic_strain_deriv_value) or + (log_dt + log_neg_deriv_eps > log_max_plastic_strain_deriv_value) or + (log_dt + log_deriv_temperature > log_max_plastic_strain_deriv_value))) { err_status = ViscoplastErrorType::failed_computation_flow_resistance_derivs; return InelasticDefgradTransvIsotropElastViscoplastUtils::PlasticStrainRateDerivs{ diff --git a/src/mat/vplast/4C_mat_vplast_reform_johnsoncook.hpp b/src/mat/vplast/4C_mat_vplast_reform_johnsoncook.hpp index 22dbf5fe59d..3c09c6fbdf7 100644 --- a/src/mat/vplast/4C_mat_vplast_reform_johnsoncook.hpp +++ b/src/mat/vplast/4C_mat_vplast_reform_johnsoncook.hpp @@ -12,6 +12,7 @@ #include "4C_comm_parobject.hpp" #include "4C_comm_parobjectfactory.hpp" #include "4C_linalg_fixedsizematrix.hpp" +#include "4C_mat_inelastic_defgrad_factors_service.hpp" #include "4C_mat_vplast_law.hpp" #include "4C_material_parameter_base.hpp" #include "4C_utils_exceptions.hpp" @@ -103,19 +104,23 @@ namespace Mat class ReformulatedJohnsonCook : public Law { public: - explicit ReformulatedJohnsonCook(Core::Mat::PAR::Parameter* params); + explicit ReformulatedJohnsonCook(Core::Mat::PAR::Parameter* params, + const InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorRegistrationSettings + error_registration_settings); - Mat::Viscoplastic::PAR::ReformulatedJohnsonCook* parameter() const override + [[nodiscard]] Mat::Viscoplastic::PAR::ReformulatedJohnsonCook* parameter() const override { return dynamic_cast( Mat::Viscoplastic::Law::parameter()); } - Core::Materials::MaterialType material_type() const override + [[nodiscard]] Core::Materials::MaterialType material_type() const override { return Core::Materials::mvl_reformulated_Johnson_Cook; }; + [[nodiscard]] bool uses_yield_surface() const override { return true; } + double evaluate_stress_ratio( const double equiv_stress, const double equiv_plastic_strain) override; @@ -123,14 +128,13 @@ namespace Mat Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status) override; double evaluate_plastic_strain_rate(const double equiv_stress, - const double equiv_plastic_strain, const double dt, const double max_plastic_strain_incr, + const double equiv_plastic_strain, const double dt, Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status, const bool update_hist_var) override; InelasticDefgradTransvIsotropElastViscoplastUtils::PlasticStrainRateDerivs evaluate_derivatives_of_plastic_strain_rate(const double equiv_stress, const double equiv_plastic_strain, const double dt, - const double max_plastic_strain_deriv_incr, Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status, const bool update_hist_var) override; @@ -140,9 +144,9 @@ namespace Mat void pre_evaluate(const Teuchos::ParameterList& params, int gp) override; - void update() override {}; + void update(const unsigned int gp) override {}; - void update_gp_state(int gp) override {}; + void update_gp_state_after_substep(const unsigned int gp) override {}; void pack_viscoplastic_law(Core::Communication::PackBuffer& data) const override; diff --git a/src/membrane/4C_membrane_evaluate.cpp b/src/membrane/4C_membrane_evaluate.cpp index e2734888c66..5a83257b187 100644 --- a/src/membrane/4C_membrane_evaluate.cpp +++ b/src/membrane/4C_membrane_evaluate.cpp @@ -965,12 +965,6 @@ void Discret::Elements::Membrane::mem_nlnstiffmass( (*massmatrix)(noddof_* i + 2, noddof_ * j + 2) += massfactor; } } - - // check for non constant mass matrix - if (solid_material()->varying_density()) - { - FOUR_C_THROW("Varying Density not supported for Membrane"); - } } /*===============================================================================* diff --git a/src/reduced_lung/src/terminal_units/4C_reduced_lung_terminal_unit_rheology.cpp b/src/reduced_lung/src/terminal_units/4C_reduced_lung_terminal_unit_rheology.cpp index 5c453abe39f..1d7cdc72b3e 100644 --- a/src/reduced_lung/src/terminal_units/4C_reduced_lung_terminal_unit_rheology.cpp +++ b/src/reduced_lung/src/terminal_units/4C_reduced_lung_terminal_unit_rheology.cpp @@ -60,7 +60,7 @@ namespace ReducedLung::TerminalUnits::Rheology (four_element_maxwell_model.elasticity_E_m[i] * dt + four_element_maxwell_model.viscosity_eta_m[i])) / data.reference_volume_v0[i] * - locally_relevant_dofs.local_values_as_span()[data.lid_q[i]] + + locally_relevant_dofs.local_values_as_span()[data.lid_q[i]] - four_element_maxwell_model.viscosity_eta_m[i] / (four_element_maxwell_model.elasticity_E_m[i] * dt + four_element_maxwell_model.viscosity_eta_m[i]) * diff --git a/src/scatra/4C_scatra_functions.hpp b/src/scatra/4C_scatra_functions.hpp index 95dff063c30..d8243ad1a8a 100644 --- a/src/scatra/4C_scatra_functions.hpp +++ b/src/scatra/4C_scatra_functions.hpp @@ -13,6 +13,7 @@ #include "4C_utils_function.hpp" #include "4C_utils_function_of_time.hpp" +#include FOUR_C_NAMESPACE_OPEN diff --git a/src/thermo/src/element/4C_thermo_ele_impl.cpp b/src/thermo/src/element/4C_thermo_ele_impl.cpp index 6466b4a55ac..d51d0b14df8 100644 --- a/src/thermo/src/element/4C_thermo_ele_impl.cpp +++ b/src/thermo/src/element/4C_thermo_ele_impl.cpp @@ -16,11 +16,15 @@ #include "4C_fem_nurbs_discretization.hpp" #include "4C_global_data.hpp" #include "4C_inpar_structure.hpp" +#include "4C_linalg_fixedsizematrix.hpp" #include "4C_linalg_fixedsizematrix_solver.hpp" #include "4C_linalg_symmetric_tensor.hpp" #include "4C_linalg_tensor_conversion.hpp" #include "4C_linalg_tensor_generators.hpp" +#include "4C_mat_multiplicative_split_defgrad_elasthyper.hpp" +#include "4C_mat_multiplicative_split_defgrad_elasthyper_service.hpp" #include "4C_mat_plasticelasthyper.hpp" +#include "4C_mat_so3_material.hpp" #include "4C_mat_thermoplastichyperelast.hpp" #include "4C_mat_thermoplasticlinelast.hpp" #include "4C_mat_thermostvenantkirchhoff.hpp" @@ -34,6 +38,7 @@ #include #include +#include FOUR_C_NAMESPACE_OPEN @@ -204,7 +209,8 @@ int Discret::Elements::TemperImpl::evaluate( // tangent ctemp plasticmat_ = false; if ((structmat->material_type() == Core::Materials::m_thermopllinelast) or - (structmat->material_type() == Core::Materials::m_thermoplhyperelast)) + (structmat->material_type() == Core::Materials::m_thermoplhyperelast) or + (structmat->material_type() == Core::Materials::m_multiplicative_split_defgrad_elasthyper)) plasticmat_ = true; } // (la.Size > 1) @@ -2064,41 +2070,40 @@ void Discret::Elements::TemperImpl::nonlinear_dissipation_fint_tang( Core::Geo::fill_initial_position_array>( ele, xyze_); - // update element geometry - Core::LinAlg::Matrix xrefe; // material coord. of element - Core::LinAlg::Matrix xcurr; // current coord. of element - - // now get current element displacements and velocities - auto nodes = ele->nodes(); - for (int i = 0; i < nen_; ++i) - { - const auto& x = nodes[i]->x(); - // (8x3) = (nen_xnsd_) - for (int j = 0; j < nsd_; ++j) - { - xrefe(i, j) = x[j]; - xcurr(i, j) = x[j] + disp[i * nsd_ + j]; - } - } - - // --------------------------------------------------------------- initialise - // thermal material tangent - Core::LinAlg::Matrix<6, 1> ctemp(Core::LinAlg::Initialization::zero); - // ------------------------------------------------------ structural material std::shared_ptr structmat = get_str_material(ele); - if (structmat->material_type() != Core::Materials::m_thermoplhyperelast) + // store possible pointers for specific material types for later use + std::shared_ptr thermoplhyperelast; + std::shared_ptr + multiplicative_split_defgrad_elast_hyper_ptr; + + if (structmat->material_type() == Core::Materials::m_thermoplhyperelast) { - FOUR_C_THROW("So far dissipation only for ThermoPlasticHyperElast material!"); + thermoplhyperelast = std::dynamic_pointer_cast(structmat); + FOUR_C_ASSERT(thermoplhyperelast != nullptr, "Cast failed."); + } + else if (structmat->material_type() == Core::Materials::m_multiplicative_split_defgrad_elasthyper) + { + multiplicative_split_defgrad_elast_hyper_ptr = + std::dynamic_pointer_cast(structmat); + FOUR_C_ASSERT(multiplicative_split_defgrad_elast_hyper_ptr != nullptr, "Cast failed."); + } + else + { + FOUR_C_THROW( + "So far dissipation only for ThermoPlasticHyperElast and " + "MultiplicativeSplitDefgradElastHyper materials!"); } - std::shared_ptr thermoplhyperelast = - std::dynamic_pointer_cast(structmat); - // true: error if cast fails // --------------------------------------------------------- time integration // get step size dt const double stepsize = params.get("delta time"); + const double total_time = params.get("total time"); + + Mat::EvaluationContext eval_context; + eval_context.total_time = &total_time; + eval_context.time_step_size = &stepsize; // ----------------------------------------- integration loop for one element @@ -2106,8 +2111,17 @@ void Discret::Elements::TemperImpl::nonlinear_dissipation_fint_tang( Core::FE::IntPointsAndWeights intpoints(Thermo::DisTypeToOptGaussRule::rule); if (intpoints.ip().nquad != nquad_) FOUR_C_THROW("Trouble with number of Gauss points"); + // update element geometry + Core::LinAlg::Matrix xcurr; // current coord. of element + Core::LinAlg::Matrix xcurrrate; // current velocity of element + + std::vector vel(disp.size(), 0.0); // dummy velocity vector + + initial_and_current_nodal_position_velocity(ele, disp, vel, xcurr, xcurrrate); + // initialise the deformation gradient w.r.t. material configuration Core::LinAlg::Matrix defgrd(Core::LinAlg::Initialization::uninitialized); + Core::LinAlg::Matrix<1, 1> current_temperature(Core::LinAlg::Initialization::uninitialized); // --------------------------------------------------- loop over Gauss Points for (int iquad = 0; iquad < intpoints.ip().nquad; ++iquad) @@ -2116,13 +2130,39 @@ void Discret::Elements::TemperImpl::nonlinear_dissipation_fint_tang( // coordinates eval_shape_func_and_derivs_at_int_point(intpoints, iquad, ele->id()); + // (material) deformation gradient F + // F = d xcurr / d xrefe = xcurr^T . N_XYZ^T + defgrd.multiply_tt(xcurr, derxy_); + + current_temperature.multiply_tn(funct_, etempn_); + // ------------------------------------------------------------ dissipation // plastic contribution thermoplastichyperelastic material - // mechanical Dissipation - // Dmech := sqrt(2/3) . sigma_y(T_{n+1}) . Dgamma/Dt - // with MechDiss := sqrt(2/3) . sigma_y(T_{n+1}) . Dgamma - const double Dmech = thermoplhyperelast->mech_diss(iquad) / stepsize; + double Dmech = 0.0; + Mat::HeatSource heat_source; + if (structmat->material_type() == Core::Materials::m_thermoplhyperelast) + { + // mechanical Dissipation + // Dmech := sqrt(2/3) . sigma_y(T_{n+1}) . Dgamma/Dt + // with MechDiss := sqrt(2/3) . sigma_y(T_{n+1}) . Dgamma + Dmech = thermoplhyperelast->mech_diss(iquad) / stepsize; + } + else if (structmat->material_type() == + Core::Materials::m_multiplicative_split_defgrad_elasthyper) + { + if constexpr (nsd_ == 3) + { + heat_source = multiplicative_split_defgrad_elast_hyper_ptr->evaluate_additional_heat_source( + eval_context, iquad, ele->id(), &defgrd, current_temperature(0)); + Dmech = heat_source.value; + } + else + { + FOUR_C_THROW( + "Dissipation currently only implemented for 3D multiplicative split materials"); + } + } // update/integrate internal force vector (coupling fraction towards displacements) if (efint != nullptr) @@ -2134,10 +2174,26 @@ void Discret::Elements::TemperImpl::nonlinear_dissipation_fint_tang( if (econd != nullptr) { - // Contribution of dissipation to cond matrix - // econd += - N_T^T . dDmech_dT/Dt . N_T - econd->multiply_nt( - (-fac_ * thermoplhyperelast->mech_diss_k_tt(iquad) / stepsize), funct_, funct_, 1.0); + if (structmat->material_type() == Core::Materials::m_thermoplhyperelast) + { + // Contribution of dissipation to cond matrix + // econd += - N_T^T . dDmech_dT/Dt . N_T + econd->multiply_nt( + (-fac_ * thermoplhyperelast->mech_diss_k_tt(iquad) / stepsize), funct_, funct_, 1.0); + } + else if (structmat->material_type() == + Core::Materials::m_multiplicative_split_defgrad_elasthyper) + { + if constexpr (nsd_ == 3) + { + econd->multiply_nt((-fac_ * heat_source.derivative_wrt_temperature), funct_, funct_, 1.0); + } + else + { + FOUR_C_THROW( + "Dissipation currently only implemented for 3D multiplicative split materials"); + } + } } } // ---------------------------------- end loop over Gauss Points @@ -2161,16 +2217,42 @@ void Discret::Elements::TemperImpl::nonlinear_dissipation_coupled_tang( Core::LinAlg::Matrix defgrd(Core::LinAlg::Initialization::uninitialized); // inverse of deformation gradient Core::LinAlg::Matrix invdefgrd(Core::LinAlg::Initialization::uninitialized); + Core::LinAlg::Matrix<1, 1> current_temperature(Core::LinAlg::Initialization::uninitialized); // ------------------------------------------------ structural material std::shared_ptr structmat = get_str_material(ele); - std::shared_ptr thermoplhyperelast = - std::dynamic_pointer_cast(structmat); - // true: error if cast fails + + // setup possible pointers for specific material types for later use + std::shared_ptr thermoplhyperelast; + std::shared_ptr + multiplicative_split_defgrad_elast_hyper; + + if (structmat->material_type() == Core::Materials::m_thermoplhyperelast) + { + thermoplhyperelast = std::dynamic_pointer_cast(structmat); + FOUR_C_ASSERT(thermoplhyperelast != nullptr, "Cast failed."); + } + else if (structmat->material_type() == Core::Materials::m_multiplicative_split_defgrad_elasthyper) + { + multiplicative_split_defgrad_elast_hyper = + std::dynamic_pointer_cast(structmat); + FOUR_C_ASSERT(multiplicative_split_defgrad_elast_hyper != nullptr, "Cast failed."); + } + else + { + FOUR_C_THROW( + "So far dissipation only for ThermoPlasticHyperElast and " + "MultiplicativeSplitDefgradElastHyper materials!"); + } // --------------------------------------------------- time integration // get step size dt const double stepsize = params.get("delta time"); + const double total_time = params.get("total time"); + + Mat::EvaluationContext eval_context; + eval_context.total_time = &total_time; + eval_context.time_step_size = &stepsize; // check the time integrator and add correct time factor const auto timint = @@ -2223,26 +2305,53 @@ void Discret::Elements::TemperImpl::nonlinear_dissipation_coupled_tang( // (material) deformation gradient F // F = d xcurr / d xrefe = xcurr^T . N_XYZ^T defgrd.multiply_tt(xcurr, derxy_); + current_temperature.multiply_tn(funct_, etempn_); // calculate the nonlinear B-operator Core::LinAlg::Matrix<6, nsd_ * nen_ * numdofpernode_> bop( Core::LinAlg::Initialization::uninitialized); calculate_bop(&bop, &defgrd, &derxy_); - // ----------------------------------------------- linearisation of Dmech_d - // k_Td += - timefac . N_T^T . 1/Dt . mechdiss_kTd . dE/dd - Core::LinAlg::Matrix<6, 1> dDmech_dE(Core::LinAlg::Initialization::uninitialized); - dDmech_dE.update(thermoplhyperelast->mech_diss_k_td(iquad)); + // Linearization of the mechanical heat-source contribution w.r.t. the + // Green-Lagrange strain. + // k_Td += - timefac . N_T^T . d(D_mech)/dE . dE/dd + Core::LinAlg::Matrix<1, 6> dDmech_dE(Core::LinAlg::Initialization::uninitialized); + + if (structmat->material_type() == Core::Materials::m_thermoplhyperelast) + { + dDmech_dE.update_t(1 / stepsize, thermoplhyperelast->mech_diss_k_td(iquad)); + } + else if (structmat->material_type() == + Core::Materials::m_multiplicative_split_defgrad_elasthyper) + { + if constexpr (nsd_ == 3) + { + const auto& mech_diss = + multiplicative_split_defgrad_elast_hyper->evaluate_additional_heat_source( + eval_context, iquad, ele->id(), &defgrd, current_temperature(0)); + + /// \f[ \frac{\mathrm{d}D_\text{mech}}{\mathrm{d}\mathbf{E}} = + /// 2\frac{\mathrm{d}D_\text{mech}}{\mathrm{d}\mathbf{C}}\f] + /// using \f[\mathbf{C} = 2\mathbf{E} + \mathbf{I}\f] + dDmech_dE.update(2.0, mech_diss.derivative_wrt_cauchy_green); + } + else + { + FOUR_C_THROW( + "Dissipation currently only implemented for 3D multiplicative split materials"); + } + } + Core::LinAlg::Matrix<1, nsd_ * nen_ * numdofpernode_> dDmech_dd( Core::LinAlg::Initialization::uninitialized); - dDmech_dd.multiply_tn(dDmech_dE, bop); + dDmech_dd.multiply(dDmech_dE, bop); // coupling stiffness matrix if (etangcoupl != nullptr) { - // k_Td^e += - timefac . N_T^T . 1/Dt . dDmech_dE . B . detJ . w(gp) + // k_Td^e += - timefac . N_T^T . d(D_mech)/dE . B . detJ . w(gp) // (8x24) = (8x1) . (1x6) (6x24) - etangcoupl->multiply_nn(-fac_ * timefac / stepsize, funct_, dDmech_dd, 1.0); + etangcoupl->multiply_nn(-fac_ * timefac, funct_, dDmech_dd, 1.0); } // (etangcoupl != nullptr) } //--------------------------------------------- end loop over Gauss Points diff --git a/src/tsi/4C_tsi_monolithic.cpp b/src/tsi/4C_tsi_monolithic.cpp index 5b0caefceae..bf3097c3289 100644 --- a/src/tsi/4C_tsi_monolithic.cpp +++ b/src/tsi/4C_tsi_monolithic.cpp @@ -1638,6 +1638,7 @@ void TSI::Monolithic::apply_str_coupl_matrix( // other parameters that might be needed by the elements sparams.set("delta time", dt()); sparams.set("total time", time()); + sparams.set("differentiationtype", static_cast(Solid::DifferentiationType::temp)); structure_field()->discretization()->clear_state(true); structure_field()->discretization()->set_state(0, "displacement", *structure_field()->dispnp()); diff --git a/tests/input_files/beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy_red_func_pol5.4C.yaml b/tests/input_files/beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy_red_func_pol5.4C.yaml new file mode 100644 index 00000000000..67f51c127cb --- /dev/null +++ b/tests/input_files/beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy_red_func_pol5.4C.yaml @@ -0,0 +1,263 @@ +TITLE: + - "Same setup as in `beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy.4C.yaml`" + - "but with the polynomial potential reduction function of order 5" +PROBLEM TYPE: + PROBLEMTYPE: "Structure" +IO: + STDOUTEVERY: 1000 + VERBOSITY: "Standard" +IO/MONITOR STRUCTURE DBC: + INTERVAL_STEPS: 1 + PRECISION_SCREEN: 3 + FILE_TYPE: csv +STRUCTURAL DYNAMIC: + DYNAMICTYPE: "Statics" + RESULTSEVERY: 100 + RESEVERYERGY: 1 + RESTARTEVERY: 100 + TIMESTEP: 0.1 + NUMSTEP: 10 + MAXTIME: 1 + TOLDISP: 1e-08 + TOLRES: 1e-06 + MAXITER: 15 + LINEAR_SOLVER: 1 +STRUCT NOX/Printing: + Inner Iteration: false + Outer Iteration StatusTest: false +SOLVER 1: + SOLVER: "UMFPACK" + NAME: "Structure_Solver" +BINNING STRATEGY: + BIN_SIZE_LOWER_BOUND: 5 + DOMAINBOUNDINGBOX: "-10.0 -10.0 -10.0 100.0 100.0 100.0" +BEAM INTERACTION: + REPARTITIONSTRATEGY: "Everydt" +beam_potential: + potential_law_exponents: [6.0] + potential_law_prefactors: [-1.0] + type: volume + strategy: single_length_specific_small_separations_simple + cutoff_radius: 100 + potential_reduction_length: 15 + potential_reduction_function: polynomial_5 +DESIGN POINT DIRICH CONDITIONS: + - E: 1 + NUMDOF: 9 + ONOFF: [1, 1, 1, 1, 1, 1, 1, 1, 1] + VAL: [0, 0, 0, 0, 0, 0, 0, 0, 0] + FUNCT: [0, 0, 0, 0, 0, 0, 0, 0, 0] + TAG: "monitor_reaction" + - E: 2 + NUMDOF: 3 + ONOFF: [1, 1, 1] + VAL: [0, 0, 0] + FUNCT: [0, 0, 0] + - E: 3 + NUMDOF: 9 + ONOFF: [1, 1, 1, 1, 1, 1, 1, 1, 1] + VAL: [1, 1, 1, 0, 0, 0, 0, 0, 0] + FUNCT: [1, 1, 1, 0, 0, 0, 0, 0, 0] + TAG: "monitor_reaction" + - E: 4 + NUMDOF: 3 + ONOFF: [1, 1, 1] + VAL: [0, 0, 0] + FUNCT: [0, 0, 0] +FUNCT1: + - SYMBOLIC_FUNCTION_OF_SPACE_TIME: "28.86751346*t" +DESIGN LINE BEAM POTENTIAL CHARGE CONDITIONS: + - E: 1 + POTLAW: 1 + VAL: 1 + - E: 2 + POTLAW: 1 + VAL: 1 +DNODE-NODE TOPOLOGY: + - "NODE 1 DNODE 1" + - "NODE 2 DNODE 2" + - "NODE 3 DNODE 1" + - "NODE 4 DNODE 2" + - "NODE 5 DNODE 1" + - "NODE 6 DNODE 2" + - "NODE 7 DNODE 1" + - "NODE 8 DNODE 2" + - "NODE 9 DNODE 1" + - "NODE 10 DNODE 2" + - "NODE 11 DNODE 1" + - "NODE 12 DNODE 2" + - "NODE 13 DNODE 1" + - "NODE 14 DNODE 2" + - "NODE 15 DNODE 1" + - "NODE 16 DNODE 2" + - "NODE 17 DNODE 1" + - "NODE 18 DNODE 2" + - "NODE 19 DNODE 1" + - "NODE 20 DNODE 2" + - "NODE 21 DNODE 1" + - "NODE 22 DNODE 3" + - "NODE 23 DNODE 4" + - "NODE 24 DNODE 3" + - "NODE 25 DNODE 4" + - "NODE 26 DNODE 3" + - "NODE 27 DNODE 4" + - "NODE 28 DNODE 3" + - "NODE 29 DNODE 4" + - "NODE 30 DNODE 3" + - "NODE 31 DNODE 4" + - "NODE 32 DNODE 3" + - "NODE 33 DNODE 4" + - "NODE 34 DNODE 3" + - "NODE 35 DNODE 4" + - "NODE 36 DNODE 3" + - "NODE 37 DNODE 4" + - "NODE 38 DNODE 3" + - "NODE 39 DNODE 4" + - "NODE 40 DNODE 3" + - "NODE 41 DNODE 4" + - "NODE 42 DNODE 3" +DLINE-NODE TOPOLOGY: + - "NODE 1 DLINE 1" + - "NODE 2 DLINE 1" + - "NODE 3 DLINE 1" + - "NODE 4 DLINE 1" + - "NODE 5 DLINE 1" + - "NODE 6 DLINE 1" + - "NODE 7 DLINE 1" + - "NODE 8 DLINE 1" + - "NODE 9 DLINE 1" + - "NODE 10 DLINE 1" + - "NODE 11 DLINE 1" + - "NODE 12 DLINE 1" + - "NODE 13 DLINE 1" + - "NODE 14 DLINE 1" + - "NODE 15 DLINE 1" + - "NODE 16 DLINE 1" + - "NODE 17 DLINE 1" + - "NODE 18 DLINE 1" + - "NODE 19 DLINE 1" + - "NODE 20 DLINE 1" + - "NODE 21 DLINE 1" + - "NODE 22 DLINE 2" + - "NODE 23 DLINE 2" + - "NODE 24 DLINE 2" + - "NODE 25 DLINE 2" + - "NODE 26 DLINE 2" + - "NODE 27 DLINE 2" + - "NODE 28 DLINE 2" + - "NODE 29 DLINE 2" + - "NODE 30 DLINE 2" + - "NODE 31 DLINE 2" + - "NODE 32 DLINE 2" + - "NODE 33 DLINE 2" + - "NODE 34 DLINE 2" + - "NODE 35 DLINE 2" + - "NODE 36 DLINE 2" + - "NODE 37 DLINE 2" + - "NODE 38 DLINE 2" + - "NODE 39 DLINE 2" + - "NODE 40 DLINE 2" + - "NODE 41 DLINE 2" + - "NODE 42 DLINE 2" +NODE COORDS: + - "NODE 1 COORD 0.00000000000000 0.00000000000000 0.00000000000000" + - "NODE 2 COORD 2.88675134594813 2.88675134594813 2.88675134594813" + - "NODE 3 COORD 5.77350269189626 5.77350269189626 5.77350269189626" + - "NODE 4 COORD 8.66025403784439 8.66025403784439 8.66025403784439" + - "NODE 5 COORD 11.54700538379252 11.54700538379252 11.54700538379252" + - "NODE 6 COORD 14.43375672974065 14.43375672974065 14.43375672974065" + - "NODE 7 COORD 17.32050807568877 17.32050807568877 17.32050807568877" + - "NODE 8 COORD 20.20725942163691 20.20725942163691 20.20725942163691" + - "NODE 9 COORD 23.09401076758503 23.09401076758503 23.09401076758503" + - "NODE 10 COORD 25.98076211353316 25.98076211353316 25.98076211353316" + - "NODE 11 COORD 28.86751345948129 28.86751345948129 28.86751345948129" + - "NODE 12 COORD 31.75426480542942 31.75426480542942 31.75426480542942" + - "NODE 13 COORD 34.64101615137755 34.64101615137755 34.64101615137755" + - "NODE 14 COORD 37.52776749732568 37.52776749732568 37.52776749732568" + - "NODE 15 COORD 40.41451884327381 40.41451884327381 40.41451884327381" + - "NODE 16 COORD 43.30127018922194 43.30127018922194 43.30127018922194" + - "NODE 17 COORD 46.18802153517007 46.18802153517007 46.18802153517007" + - "NODE 18 COORD 49.07477288111819 49.07477288111819 49.07477288111819" + - "NODE 19 COORD 51.96152422706633 51.96152422706633 51.96152422706633" + - "NODE 20 COORD 54.84827557301445 54.84827557301445 54.84827557301445" + - "NODE 21 COORD 57.73502691896258 57.73502691896258 57.73502691896258" + - "NODE 22 COORD -1.22474487139159 -1.22474487139159 2.44948974278318" + - "NODE 23 COORD 1.66200647455654 1.66200647455654 5.33624108873131" + - "NODE 24 COORD 4.54875782050467 4.54875782050467 8.22299243467944" + - "NODE 25 COORD 7.43550916645280 7.43550916645280 11.10974378062756" + - "NODE 26 COORD 10.32226051240093 10.32226051240093 13.99649512657570" + - "NODE 27 COORD 13.20901185834906 13.20901185834906 16.88324647252382" + - "NODE 28 COORD 16.09576320429719 16.09576320429719 19.76999781847195" + - "NODE 29 COORD 18.98251455024532 18.98251455024532 22.65674916442008" + - "NODE 30 COORD 21.86926589619344 21.86926589619344 25.54350051036821" + - "NODE 31 COORD 24.75601724214157 24.75601724214157 28.43025185631634" + - "NODE 32 COORD 27.64276858808970 27.64276858808970 31.31700320226447" + - "NODE 33 COORD 30.52951993403783 30.52951993403783 34.20375454821260" + - "NODE 34 COORD 33.41627127998596 33.41627127998596 37.09050589416073" + - "NODE 35 COORD 36.30302262593409 36.30302262593409 39.97725724010886" + - "NODE 36 COORD 39.18977397188223 39.18977397188223 42.86400858605699" + - "NODE 37 COORD 42.07652531783035 42.07652531783035 45.75075993200512" + - "NODE 38 COORD 44.96327666377848 44.96327666377848 48.63751127795324" + - "NODE 39 COORD 47.85002800972661 47.85002800972661 51.52426262390137" + - "NODE 40 COORD 50.73677935567474 50.73677935567474 54.41101396984951" + - "NODE 41 COORD 53.62353070162287 53.62353070162287 57.29776531579763" + - "NODE 42 COORD 56.51028204757100 56.51028204757100 60.18451666174576" +STRUCTURE ELEMENTS: + - "1 BEAM3R LINE3 1 3 2 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "2 BEAM3R LINE3 3 5 4 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "3 BEAM3R LINE3 5 7 6 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "4 BEAM3R LINE3 7 9 8 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "5 BEAM3R LINE3 9 11 10 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "6 BEAM3R LINE3 11 13 12 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "7 BEAM3R LINE3 13 15 14 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "8 BEAM3R LINE3 15 17 16 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "9 BEAM3R LINE3 17 19 18 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "10 BEAM3R LINE3 19 21 20 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "11 BEAM3R LINE3 22 24 23 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "12 BEAM3R LINE3 24 26 25 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "13 BEAM3R LINE3 26 28 27 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "14 BEAM3R LINE3 28 30 29 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "15 BEAM3R LINE3 30 32 31 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "16 BEAM3R LINE3 32 34 33 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "17 BEAM3R LINE3 34 36 35 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "18 BEAM3R LINE3 36 38 37 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "19 BEAM3R LINE3 38 40 39 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "20 BEAM3R LINE3 40 42 41 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" +MATERIALS: + - MAT: 1 + MAT_BeamReissnerElastHyper: + YOUNG: 5.4e+08 + POISSONRATIO: 0.3 + DENS: 1 + CROSSAREA: 3.1415 + SHEARCORR: 1 + MOMINPOL: 0.49702 + MOMIN2: 0.24851 + MOMIN3: 0.24851 + INTERACTIONRADIUS: 1 +RESULT DESCRIPTION: + - STRUCTURE: + SPECIAL: true + QUANTITY: "beam_interaction_potential" + VALUE: -17.4774707755639 + TOLERANCE: 1e-10 diff --git a/tests/input_files/beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy_red_func_pol7.4C.yaml b/tests/input_files/beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy_red_func_pol7.4C.yaml new file mode 100644 index 00000000000..15c741c2180 --- /dev/null +++ b/tests/input_files/beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy_red_func_pol7.4C.yaml @@ -0,0 +1,263 @@ +TITLE: + - "Same setup as in `beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy.4C.yaml`" + - "but with the polynomial potential reduction function of order 7" +PROBLEM TYPE: + PROBLEMTYPE: "Structure" +IO: + STDOUTEVERY: 1000 + VERBOSITY: "Standard" +IO/MONITOR STRUCTURE DBC: + INTERVAL_STEPS: 1 + PRECISION_SCREEN: 3 + FILE_TYPE: csv +STRUCTURAL DYNAMIC: + DYNAMICTYPE: "Statics" + RESULTSEVERY: 100 + RESEVERYERGY: 1 + RESTARTEVERY: 100 + TIMESTEP: 0.1 + NUMSTEP: 10 + MAXTIME: 1 + TOLDISP: 1e-08 + TOLRES: 1e-06 + MAXITER: 15 + LINEAR_SOLVER: 1 +STRUCT NOX/Printing: + Inner Iteration: false + Outer Iteration StatusTest: false +SOLVER 1: + SOLVER: "UMFPACK" + NAME: "Structure_Solver" +BINNING STRATEGY: + BIN_SIZE_LOWER_BOUND: 5 + DOMAINBOUNDINGBOX: "-10.0 -10.0 -10.0 100.0 100.0 100.0" +BEAM INTERACTION: + REPARTITIONSTRATEGY: "Everydt" +beam_potential: + potential_law_exponents: [6.0] + potential_law_prefactors: [-1.0] + type: volume + strategy: single_length_specific_small_separations_simple + cutoff_radius: 100 + potential_reduction_length: 15 + potential_reduction_function: polynomial_7 +DESIGN POINT DIRICH CONDITIONS: + - E: 1 + NUMDOF: 9 + ONOFF: [1, 1, 1, 1, 1, 1, 1, 1, 1] + VAL: [0, 0, 0, 0, 0, 0, 0, 0, 0] + FUNCT: [0, 0, 0, 0, 0, 0, 0, 0, 0] + TAG: "monitor_reaction" + - E: 2 + NUMDOF: 3 + ONOFF: [1, 1, 1] + VAL: [0, 0, 0] + FUNCT: [0, 0, 0] + - E: 3 + NUMDOF: 9 + ONOFF: [1, 1, 1, 1, 1, 1, 1, 1, 1] + VAL: [1, 1, 1, 0, 0, 0, 0, 0, 0] + FUNCT: [1, 1, 1, 0, 0, 0, 0, 0, 0] + TAG: "monitor_reaction" + - E: 4 + NUMDOF: 3 + ONOFF: [1, 1, 1] + VAL: [0, 0, 0] + FUNCT: [0, 0, 0] +FUNCT1: + - SYMBOLIC_FUNCTION_OF_SPACE_TIME: "28.86751346*t" +DESIGN LINE BEAM POTENTIAL CHARGE CONDITIONS: + - E: 1 + POTLAW: 1 + VAL: 1 + - E: 2 + POTLAW: 1 + VAL: 1 +DNODE-NODE TOPOLOGY: + - "NODE 1 DNODE 1" + - "NODE 2 DNODE 2" + - "NODE 3 DNODE 1" + - "NODE 4 DNODE 2" + - "NODE 5 DNODE 1" + - "NODE 6 DNODE 2" + - "NODE 7 DNODE 1" + - "NODE 8 DNODE 2" + - "NODE 9 DNODE 1" + - "NODE 10 DNODE 2" + - "NODE 11 DNODE 1" + - "NODE 12 DNODE 2" + - "NODE 13 DNODE 1" + - "NODE 14 DNODE 2" + - "NODE 15 DNODE 1" + - "NODE 16 DNODE 2" + - "NODE 17 DNODE 1" + - "NODE 18 DNODE 2" + - "NODE 19 DNODE 1" + - "NODE 20 DNODE 2" + - "NODE 21 DNODE 1" + - "NODE 22 DNODE 3" + - "NODE 23 DNODE 4" + - "NODE 24 DNODE 3" + - "NODE 25 DNODE 4" + - "NODE 26 DNODE 3" + - "NODE 27 DNODE 4" + - "NODE 28 DNODE 3" + - "NODE 29 DNODE 4" + - "NODE 30 DNODE 3" + - "NODE 31 DNODE 4" + - "NODE 32 DNODE 3" + - "NODE 33 DNODE 4" + - "NODE 34 DNODE 3" + - "NODE 35 DNODE 4" + - "NODE 36 DNODE 3" + - "NODE 37 DNODE 4" + - "NODE 38 DNODE 3" + - "NODE 39 DNODE 4" + - "NODE 40 DNODE 3" + - "NODE 41 DNODE 4" + - "NODE 42 DNODE 3" +DLINE-NODE TOPOLOGY: + - "NODE 1 DLINE 1" + - "NODE 2 DLINE 1" + - "NODE 3 DLINE 1" + - "NODE 4 DLINE 1" + - "NODE 5 DLINE 1" + - "NODE 6 DLINE 1" + - "NODE 7 DLINE 1" + - "NODE 8 DLINE 1" + - "NODE 9 DLINE 1" + - "NODE 10 DLINE 1" + - "NODE 11 DLINE 1" + - "NODE 12 DLINE 1" + - "NODE 13 DLINE 1" + - "NODE 14 DLINE 1" + - "NODE 15 DLINE 1" + - "NODE 16 DLINE 1" + - "NODE 17 DLINE 1" + - "NODE 18 DLINE 1" + - "NODE 19 DLINE 1" + - "NODE 20 DLINE 1" + - "NODE 21 DLINE 1" + - "NODE 22 DLINE 2" + - "NODE 23 DLINE 2" + - "NODE 24 DLINE 2" + - "NODE 25 DLINE 2" + - "NODE 26 DLINE 2" + - "NODE 27 DLINE 2" + - "NODE 28 DLINE 2" + - "NODE 29 DLINE 2" + - "NODE 30 DLINE 2" + - "NODE 31 DLINE 2" + - "NODE 32 DLINE 2" + - "NODE 33 DLINE 2" + - "NODE 34 DLINE 2" + - "NODE 35 DLINE 2" + - "NODE 36 DLINE 2" + - "NODE 37 DLINE 2" + - "NODE 38 DLINE 2" + - "NODE 39 DLINE 2" + - "NODE 40 DLINE 2" + - "NODE 41 DLINE 2" + - "NODE 42 DLINE 2" +NODE COORDS: + - "NODE 1 COORD 0.00000000000000 0.00000000000000 0.00000000000000" + - "NODE 2 COORD 2.88675134594813 2.88675134594813 2.88675134594813" + - "NODE 3 COORD 5.77350269189626 5.77350269189626 5.77350269189626" + - "NODE 4 COORD 8.66025403784439 8.66025403784439 8.66025403784439" + - "NODE 5 COORD 11.54700538379252 11.54700538379252 11.54700538379252" + - "NODE 6 COORD 14.43375672974065 14.43375672974065 14.43375672974065" + - "NODE 7 COORD 17.32050807568877 17.32050807568877 17.32050807568877" + - "NODE 8 COORD 20.20725942163691 20.20725942163691 20.20725942163691" + - "NODE 9 COORD 23.09401076758503 23.09401076758503 23.09401076758503" + - "NODE 10 COORD 25.98076211353316 25.98076211353316 25.98076211353316" + - "NODE 11 COORD 28.86751345948129 28.86751345948129 28.86751345948129" + - "NODE 12 COORD 31.75426480542942 31.75426480542942 31.75426480542942" + - "NODE 13 COORD 34.64101615137755 34.64101615137755 34.64101615137755" + - "NODE 14 COORD 37.52776749732568 37.52776749732568 37.52776749732568" + - "NODE 15 COORD 40.41451884327381 40.41451884327381 40.41451884327381" + - "NODE 16 COORD 43.30127018922194 43.30127018922194 43.30127018922194" + - "NODE 17 COORD 46.18802153517007 46.18802153517007 46.18802153517007" + - "NODE 18 COORD 49.07477288111819 49.07477288111819 49.07477288111819" + - "NODE 19 COORD 51.96152422706633 51.96152422706633 51.96152422706633" + - "NODE 20 COORD 54.84827557301445 54.84827557301445 54.84827557301445" + - "NODE 21 COORD 57.73502691896258 57.73502691896258 57.73502691896258" + - "NODE 22 COORD -1.22474487139159 -1.22474487139159 2.44948974278318" + - "NODE 23 COORD 1.66200647455654 1.66200647455654 5.33624108873131" + - "NODE 24 COORD 4.54875782050467 4.54875782050467 8.22299243467944" + - "NODE 25 COORD 7.43550916645280 7.43550916645280 11.10974378062756" + - "NODE 26 COORD 10.32226051240093 10.32226051240093 13.99649512657570" + - "NODE 27 COORD 13.20901185834906 13.20901185834906 16.88324647252382" + - "NODE 28 COORD 16.09576320429719 16.09576320429719 19.76999781847195" + - "NODE 29 COORD 18.98251455024532 18.98251455024532 22.65674916442008" + - "NODE 30 COORD 21.86926589619344 21.86926589619344 25.54350051036821" + - "NODE 31 COORD 24.75601724214157 24.75601724214157 28.43025185631634" + - "NODE 32 COORD 27.64276858808970 27.64276858808970 31.31700320226447" + - "NODE 33 COORD 30.52951993403783 30.52951993403783 34.20375454821260" + - "NODE 34 COORD 33.41627127998596 33.41627127998596 37.09050589416073" + - "NODE 35 COORD 36.30302262593409 36.30302262593409 39.97725724010886" + - "NODE 36 COORD 39.18977397188223 39.18977397188223 42.86400858605699" + - "NODE 37 COORD 42.07652531783035 42.07652531783035 45.75075993200512" + - "NODE 38 COORD 44.96327666377848 44.96327666377848 48.63751127795324" + - "NODE 39 COORD 47.85002800972661 47.85002800972661 51.52426262390137" + - "NODE 40 COORD 50.73677935567474 50.73677935567474 54.41101396984951" + - "NODE 41 COORD 53.62353070162287 53.62353070162287 57.29776531579763" + - "NODE 42 COORD 56.51028204757100 56.51028204757100 60.18451666174576" +STRUCTURE ELEMENTS: + - "1 BEAM3R LINE3 1 3 2 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "2 BEAM3R LINE3 3 5 4 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "3 BEAM3R LINE3 5 7 6 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "4 BEAM3R LINE3 7 9 8 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "5 BEAM3R LINE3 9 11 10 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "6 BEAM3R LINE3 11 13 12 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "7 BEAM3R LINE3 13 15 14 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "8 BEAM3R LINE3 15 17 16 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "9 BEAM3R LINE3 17 19 18 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "10 BEAM3R LINE3 19 21 20 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "11 BEAM3R LINE3 22 24 23 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "12 BEAM3R LINE3 24 26 25 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "13 BEAM3R LINE3 26 28 27 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "14 BEAM3R LINE3 28 30 29 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "15 BEAM3R LINE3 30 32 31 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "16 BEAM3R LINE3 32 34 33 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "17 BEAM3R LINE3 34 36 35 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "18 BEAM3R LINE3 36 38 37 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "19 BEAM3R LINE3 38 40 39 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" + - "20 BEAM3R LINE3 40 42 41 MAT 1 TRIADS 0.0 -0.675510858856040 0.675510858856040 0.0 -0.675510858856040 + 0.675510858856040 0.0 -0.675510858856040 0.675510858856040 HERMITE_CENTERLINE true" +MATERIALS: + - MAT: 1 + MAT_BeamReissnerElastHyper: + YOUNG: 5.4e+08 + POISSONRATIO: 0.3 + DENS: 1 + CROSSAREA: 3.1415 + SHEARCORR: 1 + MOMINPOL: 0.49702 + MOMIN2: 0.24851 + MOMIN3: 0.24851 + INTERACTIONRADIUS: 1 +RESULT DESCRIPTION: + - STRUCTURE: + SPECIAL: true + QUANTITY: "beam_interaction_potential" + VALUE: -17.4774266763426 + TOLERANCE: 1e-10 diff --git a/tests/input_files/mat_iso_thermoviscoplast_refJC_log_timint_tsi_monolithic.4C.yaml b/tests/input_files/mat_iso_thermoviscoplast_refJC_log_timint_tsi_monolithic.4C.yaml new file mode 100644 index 00000000000..e64328eb8dc --- /dev/null +++ b/tests/input_files/mat_iso_thermoviscoplast_refJC_log_timint_tsi_monolithic.4C.yaml @@ -0,0 +1,326 @@ +PROBLEM TYPE: + PROBLEMTYPE: "Thermo_Structure_Interaction" +IO: + STRUCT_STRESS: "Cauchy" + STRUCT_STRAIN: "LOG" +IO/RUNTIME VTK OUTPUT/STRUCTURE: + OUTPUT_STRUCTURE: true + DISPLACEMENT: true + STRESS_STRAIN: true +IO/RUNTIME VTK OUTPUT: + INTERVAL_STEPS: 1 +STRUCTURAL DYNAMIC: + DYNAMICTYPE: "Statics" + TOLDISP: 1e-08 + NEGLECTINERTIA: true + LINEAR_SOLVER: 1 +THERMAL DYNAMIC: + DYNAMICTYPE: OneStepTheta + INITIALFIELD: "field_by_function" + INITFUNCNO: 2 + TOLTEMP: 1e-08 + NORM_TEMP: Abs + TOLRES: 1e-06 + NORM_RESF: Abs + NORMCOMBI_RESFTEMP: And + ITERNORM: L2 + PREDICT: ConstTemp + ADAPTCONV: false + ADAPTCONV_BETTER: 0.1 + LUMPCAPA: false + LINEAR_SOLVER: 1 +THERMAL DYNAMIC/RUNTIME VTK OUTPUT: + OUTPUT_THERMO: true + TEMPERATURE: true +TSI DYNAMIC: + COUPALGO: tsi_monolithic + MATCHINGGRID: true + RESTARTEVERY: 30 + NUMSTEP: 100000000 + MAXTIME: 0.0001 # [s] + TIMESTEP: 1e-6 # [s] + ITEMAX: 10 + ITEMIN: 0 + RESULTSEVERY: 1 + NORM_INC: Abs +TSI DYNAMIC/MONOLITHIC: + LINEAR_SOLVER: 1 + MERGE_TSI_BLOCK_MATRIX: true + TOLINC: 1e-08 + CONVTOL: 1e-08 + NORM_RESF: Abs +SOLVER 1: + SOLVER: UMFPACK +MATERIALS: + - MAT: 1 + MAT_MultiplicativeSplitDefgradElastHyper: + NUMMATEL: 1 + MATIDSEL: [2] + NUMFACINEL: 1 + INELDEFGRADFACIDS: [3] + DENS: 7830e-12 # [t/mm^3 = N*s^2/mm^4] + REF_TEMPERATURE: 293.0 # [K] + THERMAL_EXPANSION_COEFFICIENT: 11e-6 # [1/K] + - MAT: 2 + ELAST_CoupNeoHooke: + YOUNG: 200000 # [N/mm^2] + NUE: 0.29 # [-] + - MAT: 3 + MAT_InelasticDefgradTransvIsotropElastViscoplast: + VISCOPLAST_LAW_ID: 4 + TAYLOR_QUINNEY_COEFFICIENT: 0.85 # [-] + FIBER_READER_ID: 5 + MAT_BEHAVIOR: "isotropic" + TIME_INTEGRATION_HIST_VARS: logarithmic + LOCAL_NEWTON: + CONV_CHECK: residual_and_increment_ratio + MAX_ITER: 100 + RES_TOL: 1e-8 + INCR_TOL: 1e-8 + MAX_EXCEEDANCE_FACT_RES_TOL: 10 + MAX_EXCEEDANCE_FACT_INCR_TOL: 10 + DIVER_CONT: stop + - MAT: 4 + MAT_ViscoplasticLawReformulatedJohnsonCook: + STRAIN_RATE_PREFAC: 1 # [1/s] + STRAIN_RATE_EXP_FAC: 0.014 # [-] + INIT_YIELD_STRENGTH: 792 # [N/mm^2] + ISOTROP_HARDEN_PREFAC: 510 # [N/mm^2] + ISOTROP_HARDEN_EXP: 0.26 # [-] + REF_TEMPERATURE: 293.0 # [K] + TEMPERATURE_SENS: 1.03 # [-] + MELT_TEMPERATURE: 1793 # [K] + - MAT: 5 + ELAST_CoupTransverselyIsotropic: + ALPHA: 1 + BETA: 1 + GAMMA: 1 + ANGLE: 0 + STR_TENS_ID: 100 + - MAT: 100 + ELAST_StructuralTensor: + STRATEGY: "Standard" + + - MAT: 10 + MAT_Fourier: + CAPA: 3.734910 # [mJ/(mm^3*K) = N/(mm^2*K)] + CONDUCT: + constant: [37] # [mW/(mm*K) = N/s/K] + +CLONING MATERIAL MAP: + - SRC_FIELD: structure + SRC_MAT: 1 + TAR_FIELD: thermo + TAR_MAT: 10 + +FUNCT1: + - SYMBOLIC_FUNCTION_OF_SPACE_TIME: "a" + - VARIABLE: 0 + NAME: "a" + TYPE: "multifunction" + NUMPOINTS: 2 + TIMES: [0, 1.6e+16] + DESCRIPTION: ["(exp(1.0e2*t)-1.0)"] # [mm] +FUNCT2: + - SYMBOLIC_FUNCTION_OF_SPACE_TIME: "temperature_initial_field" + - VARIABLE: 0 + TYPE: expression + NAME: "temperature_initial_field" + DESCRIPTION: "293" +RESULT DESCRIPTION: + - STRUCTURE: + DIS: "structure" + NODE: 4 + QUANTITY: "dispy" + VALUE: -0.00394895027488 + TOLERANCE: 1e-14 + - STRUCTURE: + DIS: "structure" + NODE: 5 + QUANTITY: "dispx" + VALUE: -0.00394895027488 + TOLERANCE: 1e-14 + - STRUCTURE: + DIS: "structure" + NODE: 8 + QUANTITY: "dispx" + VALUE: -0.00394895027488 + TOLERANCE: 1e-14 + - STRUCTURE: + DIS: "structure" + NODE: 8 + QUANTITY: "dispy" + VALUE: -0.00394895027488 + TOLERANCE: 1e-14 + - STRUCTURE: + DIS: "structure" + NODE: 8 + QUANTITY: "dispz" + VALUE: 0.010050167084167949 + TOLERANCE: 1e-14 + - STRUCTURE: + DIS: "structure" + NODE: 6 + QUANTITY: "dispx" + VALUE: -0.00394895027488 + TOLERANCE: 1e-14 + - STRUCTURE: + DIS: "structure" + NODE: 4 + QUANTITY: "stress_zz" + VALUE: 977.652620618 + TOLERANCE: 1e-8 + - STRUCTURE: + DIS: "structure" + NODE: 8 + QUANTITY: "stress_zz" + VALUE: 977.652620618 + TOLERANCE: 1e-8 + - THERMAL: + DIS: thermo + NODE: 1 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 + - THERMAL: + DIS: thermo + NODE: 2 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 + - THERMAL: + DIS: thermo + NODE: 3 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 + - THERMAL: + DIS: thermo + NODE: 4 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 + - THERMAL: + DIS: thermo + NODE: 5 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 + - THERMAL: + DIS: thermo + NODE: 6 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 + - THERMAL: + DIS: thermo + NODE: 7 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 + - THERMAL: + DIS: thermo + NODE: 8 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-10 +DESIGN POINT DIRICH CONDITIONS: + - E: 1 + NUMDOF: 3 + ONOFF: [1, 1, 1] + VAL: [0, 0, 0] + FUNCT: [null, null, null] + - E: 2 + NUMDOF: 3 + ONOFF: [1, 1, 1] + VAL: [0, 0, 1] + FUNCT: [null, null, 1] +DESIGN LINE DIRICH CONDITIONS: + - E: 1 + NUMDOF: 3 + ONOFF: [1, 0, 1] + VAL: [0, 0, 1] + FUNCT: [null, null, 1] + - E: 2 + NUMDOF: 3 + ONOFF: [0, 1, 1] + VAL: [0, 0, 1] + FUNCT: [null, null, 1] + - E: 3 + NUMDOF: 3 + ONOFF: [1, 1, 0] + VAL: [0, 0, 0] + FUNCT: [null, null, null] + - E: 4 + NUMDOF: 3 + ONOFF: [1, 0, 1] + VAL: [0, 0, 0] + FUNCT: [null, null, null] + - E: 5 + NUMDOF: 3 + ONOFF: [0, 1, 1] + VAL: [0, 0, 0] + FUNCT: [null, null, null] +DESIGN SURF DIRICH CONDITIONS: + - E: 1 + NUMDOF: 3 + ONOFF: [0, 0, 1] + VAL: [0, 0, 1] + FUNCT: [null, null, 1] + - E: 2 + NUMDOF: 3 + ONOFF: [0, 0, 1] + VAL: [0, 0, 0] + FUNCT: [null, null, null] + - E: 3 + NUMDOF: 3 + ONOFF: [1, 0, 0] + VAL: [0, 0, 0] + FUNCT: [null, null, null] + - E: 4 + NUMDOF: 3 + ONOFF: [0, 1, 0] + VAL: [0, 0, 0] + FUNCT: [null, null, null] +DNODE-NODE TOPOLOGY: + - "NODE 2 DNODE 1" + - "NODE 1 DNODE 2" +DLINE-NODE TOPOLOGY: + - "NODE 1 DLINE 1" + - "NODE 4 DLINE 1" + - "NODE 1 DLINE 2" + - "NODE 5 DLINE 2" + - "NODE 1 DLINE 3" + - "NODE 2 DLINE 3" + - "NODE 2 DLINE 4" + - "NODE 3 DLINE 4" + - "NODE 2 DLINE 5" + - "NODE 6 DLINE 5" +DSURF-NODE TOPOLOGY: + - "NODE 1 DSURFACE 1" + - "NODE 4 DSURFACE 1" + - "NODE 5 DSURFACE 1" + - "NODE 8 DSURFACE 1" + - "NODE 2 DSURFACE 2" + - "NODE 3 DSURFACE 2" + - "NODE 6 DSURFACE 2" + - "NODE 7 DSURFACE 2" + - "NODE 1 DSURFACE 3" + - "NODE 2 DSURFACE 3" + - "NODE 3 DSURFACE 3" + - "NODE 4 DSURFACE 3" + - "NODE 1 DSURFACE 4" + - "NODE 2 DSURFACE 4" + - "NODE 5 DSURFACE 4" + - "NODE 6 DSURFACE 4" +NODE COORDS: + - "NODE 1 COORD -5.0000000000000000e-01 -5.0000000000000000e-01 5.0000000000000000e-01" + - "NODE 2 COORD -5.0000000000000000e-01 -5.0000000000000000e-01 -5.0000000000000000e-01" + - "NODE 3 COORD -5.0000000000000000e-01 5.0000000000000000e-01 -5.0000000000000000e-01" + - "NODE 4 COORD -5.0000000000000000e-01 5.0000000000000000e-01 5.0000000000000000e-01" + - "NODE 5 COORD 5.0000000000000000e-01 -5.0000000000000000e-01 5.0000000000000000e-01" + - "NODE 6 COORD 5.0000000000000000e-01 -5.0000000000000000e-01 -5.0000000000000000e-01" + - "NODE 7 COORD 5.0000000000000000e-01 5.0000000000000000e-01 -5.0000000000000000e-01" + - "NODE 8 COORD 5.0000000000000000e-01 5.0000000000000000e-01 5.0000000000000000e-01" +STRUCTURE ELEMENTS: + - "1 SOLIDSCATRA HEX8 1 2 3 4 5 6 7 8 MAT 1 KINEM nonlinear FIBER1 0 0 1.0 TYPE Undefined" diff --git a/tests/input_files/mat_iso_thermoviscoplast_refJC_log_timint_tsi_partitioned.4C.yaml b/tests/input_files/mat_iso_thermoviscoplast_refJC_log_timint_tsi_partitioned.4C.yaml new file mode 100644 index 00000000000..08b66316a04 --- /dev/null +++ b/tests/input_files/mat_iso_thermoviscoplast_refJC_log_timint_tsi_partitioned.4C.yaml @@ -0,0 +1,329 @@ +PROBLEM TYPE: + PROBLEMTYPE: "Thermo_Structure_Interaction" +IO: + STRUCT_STRESS: "Cauchy" + STRUCT_STRAIN: "LOG" +IO/RUNTIME VTK OUTPUT/STRUCTURE: + OUTPUT_STRUCTURE: true + DISPLACEMENT: true + STRESS_STRAIN: true +IO/RUNTIME VTK OUTPUT: + INTERVAL_STEPS: 1 +STRUCTURAL DYNAMIC: + DYNAMICTYPE: "Statics" + RESTARTEVERY: 30 + TOLDISP: 1e-08 + NEGLECTINERTIA: true + LINEAR_SOLVER: 1 +THERMAL DYNAMIC: + DYNAMICTYPE: OneStepTheta + INITIALFIELD: "field_by_function" + INITFUNCNO: 2 + TOLTEMP: 1e-08 + NORM_TEMP: Abs + TOLRES: 1e-06 + NORM_RESF: Abs + NORMCOMBI_RESFTEMP: And + MAXITER: 50 + MINITER: 0 + ITERNORM: L2 + NLNSOL: fullnewton + PREDICT: ConstTemp + ADAPTCONV: false + ADAPTCONV_BETTER: 0.1 + LUMPCAPA: false + LINEAR_SOLVER: 1 + CALCERROR: "No" + CALCERRORFUNCNO: -1 +THERMAL DYNAMIC/RUNTIME VTK OUTPUT: + OUTPUT_THERMO: true + TEMPERATURE: true +TSI DYNAMIC: + COUPALGO: tsi_iterstagg + MATCHINGGRID: true + RESTARTEVERY: 30 + NUMSTEP: 100000000 + MAXTIME: 0.0001 # [s] + TIMESTEP: 1e-6 # [s] + ITEMAX: 10 + ITEMIN: 0 + RESULTSEVERY: 1 + NORM_INC: Abs +TSI DYNAMIC/PARTITIONED: + CONVTOL: 1e-10 + COUPVARIABLE: Temperature +SOLVER 1: + SOLVER: "UMFPACK" +MATERIALS: + - MAT: 1 + MAT_MultiplicativeSplitDefgradElastHyper: + NUMMATEL: 1 + MATIDSEL: [2] + NUMFACINEL: 1 + INELDEFGRADFACIDS: [3] + DENS: 7830e-12 # [t/mm^3 = N*s^2/mm^4] + REF_TEMPERATURE: 293.0 # [K] + THERMAL_EXPANSION_COEFFICIENT: 11e-6 # [1/K] + - MAT: 2 + ELAST_CoupNeoHooke: + YOUNG: 200000 # [N/mm^2] + NUE: 0.29 # [-] + - MAT: 3 + MAT_InelasticDefgradTransvIsotropElastViscoplast: + VISCOPLAST_LAW_ID: 4 + TAYLOR_QUINNEY_COEFFICIENT: 0.85 # [-] + FIBER_READER_ID: 5 + MAT_BEHAVIOR: "isotropic" + TIME_INTEGRATION_HIST_VARS: logarithmic + LOCAL_NEWTON: + CONV_CHECK: residual_and_increment_ratio + MAX_ITER: 100 + RES_TOL: 1e-8 + INCR_TOL: 1e-8 + MAX_EXCEEDANCE_FACT_RES_TOL: 10 + MAX_EXCEEDANCE_FACT_INCR_TOL: 10 + DIVER_CONT: stop + - MAT: 4 + MAT_ViscoplasticLawReformulatedJohnsonCook: + STRAIN_RATE_PREFAC: 1 # [1/s] + STRAIN_RATE_EXP_FAC: 0.014 # [-] + INIT_YIELD_STRENGTH: 792 # [N/mm^2] + ISOTROP_HARDEN_PREFAC: 510 # [N/mm^2] + ISOTROP_HARDEN_EXP: 0.26 # [-] + REF_TEMPERATURE: 293.0 # [K] + TEMPERATURE_SENS: 1.03 # [-] + MELT_TEMPERATURE: 1793 # [K] + - MAT: 5 + ELAST_CoupTransverselyIsotropic: + ALPHA: 1 + BETA: 1 + GAMMA: 1 + ANGLE: 0 + STR_TENS_ID: 100 + - MAT: 100 + ELAST_StructuralTensor: + STRATEGY: "Standard" + + - MAT: 10 + MAT_Fourier: + CAPA: 3.734910 # [mJ/(mm^3*K) = N/(mm^2*K)] + CONDUCT: + constant: [37] # [mW/(mm*K) = N/s/K] + +CLONING MATERIAL MAP: + - SRC_FIELD: structure + SRC_MAT: 1 + TAR_FIELD: thermo + TAR_MAT: 10 + +FUNCT1: + - SYMBOLIC_FUNCTION_OF_SPACE_TIME: "a" + - VARIABLE: 0 + NAME: "a" + TYPE: "multifunction" + NUMPOINTS: 2 + TIMES: [0, 1.6e+16] + DESCRIPTION: ["(exp(1.0e2*t)-1.0)"] # [mm] +FUNCT2: + - SYMBOLIC_FUNCTION_OF_SPACE_TIME: "temperature_initial_field" + - VARIABLE: 0 + TYPE: expression + NAME: "temperature_initial_field" + DESCRIPTION: "293" +RESULT DESCRIPTION: + - STRUCTURE: + DIS: "structure" + NODE: 4 + QUANTITY: "dispy" + VALUE: -0.00394895027488 + TOLERANCE: 1e-14 + - STRUCTURE: + DIS: "structure" + NODE: 5 + QUANTITY: "dispx" + VALUE: -0.00394895027488 + TOLERANCE: 1e-14 + - STRUCTURE: + DIS: "structure" + NODE: 8 + QUANTITY: "dispx" + VALUE: -0.00394895027488 + TOLERANCE: 1e-14 + - STRUCTURE: + DIS: "structure" + NODE: 8 + QUANTITY: "dispy" + VALUE: -0.00394895027488 + TOLERANCE: 1e-14 + - STRUCTURE: + DIS: "structure" + NODE: 8 + QUANTITY: "dispz" + VALUE: 0.010050167084167949 + TOLERANCE: 1e-14 + - STRUCTURE: + DIS: "structure" + NODE: 6 + QUANTITY: "dispx" + VALUE: -0.00394895027488 + TOLERANCE: 1e-14 + - STRUCTURE: + DIS: "structure" + NODE: 4 + QUANTITY: "stress_zz" + VALUE: 977.652620618 + TOLERANCE: 1e-8 + - STRUCTURE: + DIS: "structure" + NODE: 8 + QUANTITY: "stress_zz" + VALUE: 977.652620618 + TOLERANCE: 1e-8 + - THERMAL: + DIS: thermo + NODE: 1 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 + - THERMAL: + DIS: thermo + NODE: 2 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 + - THERMAL: + DIS: thermo + NODE: 3 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 + - THERMAL: + DIS: thermo + NODE: 4 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 + - THERMAL: + DIS: thermo + NODE: 5 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 + - THERMAL: + DIS: thermo + NODE: 6 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 + - THERMAL: + DIS: thermo + NODE: 7 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 + - THERMAL: + DIS: thermo + NODE: 8 + QUANTITY: temp + VALUE: 294.095019277192 + TOLERANCE: 1e-11 +DESIGN POINT DIRICH CONDITIONS: + - E: 1 + NUMDOF: 3 + ONOFF: [1, 1, 1] + VAL: [0, 0, 0] + FUNCT: [null, null, null] + - E: 2 + NUMDOF: 3 + ONOFF: [1, 1, 1] + VAL: [0, 0, 1] + FUNCT: [null, null, 1] +DESIGN LINE DIRICH CONDITIONS: + - E: 1 + NUMDOF: 3 + ONOFF: [1, 0, 1] + VAL: [0, 0, 1] + FUNCT: [null, null, 1] + - E: 2 + NUMDOF: 3 + ONOFF: [0, 1, 1] + VAL: [0, 0, 1] + FUNCT: [null, null, 1] + - E: 3 + NUMDOF: 3 + ONOFF: [1, 1, 0] + VAL: [0, 0, 0] + FUNCT: [null, null, null] + - E: 4 + NUMDOF: 3 + ONOFF: [1, 0, 1] + VAL: [0, 0, 0] + FUNCT: [null, null, null] + - E: 5 + NUMDOF: 3 + ONOFF: [0, 1, 1] + VAL: [0, 0, 0] + FUNCT: [null, null, null] +DESIGN SURF DIRICH CONDITIONS: + - E: 1 + NUMDOF: 3 + ONOFF: [0, 0, 1] + VAL: [0, 0, 1] + FUNCT: [null, null, 1] + - E: 2 + NUMDOF: 3 + ONOFF: [0, 0, 1] + VAL: [0, 0, 0] + FUNCT: [null, null, null] + - E: 3 + NUMDOF: 3 + ONOFF: [1, 0, 0] + VAL: [0, 0, 0] + FUNCT: [null, null, null] + - E: 4 + NUMDOF: 3 + ONOFF: [0, 1, 0] + VAL: [0, 0, 0] + FUNCT: [null, null, null] +DNODE-NODE TOPOLOGY: + - "NODE 2 DNODE 1" + - "NODE 1 DNODE 2" +DLINE-NODE TOPOLOGY: + - "NODE 1 DLINE 1" + - "NODE 4 DLINE 1" + - "NODE 1 DLINE 2" + - "NODE 5 DLINE 2" + - "NODE 1 DLINE 3" + - "NODE 2 DLINE 3" + - "NODE 2 DLINE 4" + - "NODE 3 DLINE 4" + - "NODE 2 DLINE 5" + - "NODE 6 DLINE 5" +DSURF-NODE TOPOLOGY: + - "NODE 1 DSURFACE 1" + - "NODE 4 DSURFACE 1" + - "NODE 5 DSURFACE 1" + - "NODE 8 DSURFACE 1" + - "NODE 2 DSURFACE 2" + - "NODE 3 DSURFACE 2" + - "NODE 6 DSURFACE 2" + - "NODE 7 DSURFACE 2" + - "NODE 1 DSURFACE 3" + - "NODE 2 DSURFACE 3" + - "NODE 3 DSURFACE 3" + - "NODE 4 DSURFACE 3" + - "NODE 1 DSURFACE 4" + - "NODE 2 DSURFACE 4" + - "NODE 5 DSURFACE 4" + - "NODE 6 DSURFACE 4" +NODE COORDS: + - "NODE 1 COORD -5.0000000000000000e-01 -5.0000000000000000e-01 5.0000000000000000e-01" + - "NODE 2 COORD -5.0000000000000000e-01 -5.0000000000000000e-01 -5.0000000000000000e-01" + - "NODE 3 COORD -5.0000000000000000e-01 5.0000000000000000e-01 -5.0000000000000000e-01" + - "NODE 4 COORD -5.0000000000000000e-01 5.0000000000000000e-01 5.0000000000000000e-01" + - "NODE 5 COORD 5.0000000000000000e-01 -5.0000000000000000e-01 5.0000000000000000e-01" + - "NODE 6 COORD 5.0000000000000000e-01 -5.0000000000000000e-01 -5.0000000000000000e-01" + - "NODE 7 COORD 5.0000000000000000e-01 5.0000000000000000e-01 -5.0000000000000000e-01" + - "NODE 8 COORD 5.0000000000000000e-01 5.0000000000000000e-01 5.0000000000000000e-01" +STRUCTURE ELEMENTS: + - "1 SOLIDSCATRA HEX8 1 2 3 4 5 6 7 8 MAT 1 KINEM nonlinear FIBER1 0 0 1.0 TYPE Undefined" diff --git a/tests/input_files/mat_iso_viscoplast_refJC_log_timint.4C.yaml b/tests/input_files/mat_iso_viscoplast_refJC_log_timint.4C.yaml index cf03bdf6e75..b0171450079 100644 --- a/tests/input_files/mat_iso_viscoplast_refJC_log_timint.4C.yaml +++ b/tests/input_files/mat_iso_viscoplast_refJC_log_timint.4C.yaml @@ -59,6 +59,11 @@ MATERIALS: MAX_EXCEEDANCE_FACT_RES_TOL: 10 MAX_EXCEEDANCE_FACT_INCR_TOL: 10 DIVER_CONT: stop + ERROR_REGISTRATION_SETTINGS: + REGISTER_PLASTIC_STRAIN_INCR_OVERFLOW: true + MAX_PLASTIC_STRAIN_INCR: 10686474581524.463 + REGISTER_PLASTIC_STRAIN_DERIV_INCR_OVERFLOW: false + MAX_PLASTIC_STRAIN_DERIV_INCR: 10686474581524.463 - MAT: 4 MAT_ViscoplasticLawReformulatedJohnsonCook: STRAIN_RATE_PREFAC: 1 diff --git a/tests/input_files/mat_iso_viscoplast_refJC_log_timint_substepping.4C.yaml b/tests/input_files/mat_iso_viscoplast_refJC_log_timint_substepping.4C.yaml index 441ddc3055a..7a2a3b78b26 100644 --- a/tests/input_files/mat_iso_viscoplast_refJC_log_timint_substepping.4C.yaml +++ b/tests/input_files/mat_iso_viscoplast_refJC_log_timint_substepping.4C.yaml @@ -95,25 +95,25 @@ RESULT DESCRIPTION: DIS: "structure" NODE: 4 QUANTITY: "dispy" - VALUE: -4.01592180458057706e-03 + VALUE: -4.01558458395893415e-03 TOLERANCE: 4e-11 - STRUCTURE: DIS: "structure" NODE: 5 QUANTITY: "dispx" - VALUE: -4.01592180458140973e-03 + VALUE: -4.01558458395998453e-03 TOLERANCE: 4e-11 - STRUCTURE: DIS: "structure" NODE: 8 QUANTITY: "dispx" - VALUE: -4.01592180458110789e-03 + VALUE: -4.01558458395858894e-03 TOLERANCE: 4e-11 - STRUCTURE: DIS: "structure" NODE: 8 QUANTITY: "dispy" - VALUE: -4.01592180458025701e-03 + VALUE: -4.01558458395919263e-03 TOLERANCE: 4e-11 - STRUCTURE: DIS: "structure" @@ -125,19 +125,19 @@ RESULT DESCRIPTION: DIS: "structure" NODE: 6 QUANTITY: "dispx" - VALUE: -4.01592180458238204e-03 + VALUE: -4.01558458395947105e-03 TOLERANCE: 4e-11 - STRUCTURE: DIS: "structure" NODE: 4 QUANTITY: "stress_zz" - VALUE: 9.30776106020185466e+02 + VALUE: 9.31099439482890148e+02 TOLERANCE: 0.00098 - STRUCTURE: DIS: "structure" NODE: 8 QUANTITY: "stress_zz" - VALUE: 9.30776106016615358e+02 + VALUE: 9.31099439481397212e+02 TOLERANCE: 0.00098 DESIGN POINT DIRICH CONDITIONS: - E: 1 diff --git a/tests/input_files/mat_solid_superposition.4C.yaml b/tests/input_files/mat_solid_superposition.4C.yaml new file mode 100644 index 00000000000..8496b0686e4 --- /dev/null +++ b/tests/input_files/mat_solid_superposition.4C.yaml @@ -0,0 +1,185 @@ +TITLE: + - Testcase for testing the superposition for 3D solid materials (MAT_Solid_Superposition) + - The setup of the test-case is a single cube with HEX8 elements. + - The cube is fixed on the bottom surface (z=0). On the top surface (z=1), a surface force is applied + in x-, y- and z-direction subsequently. + - The test uses the MAT_Solid_Superposition with two St. Venant Kirchhoff constituents with Young moduli + 200 and 600 (summing to 800). + - The results match a single St. Venant Kirchhoff material with Young's modulus 800, verifying linear + superposition of stresses and tangents. +PROBLEM TYPE: + PROBLEMTYPE: "Structure" +IO: + STRUCT_STRESS: "2PK" + STRUCT_STRAIN: "GL" +IO/RUNTIME VTK OUTPUT: + INTERVAL_STEPS: 1 +IO/RUNTIME VTK OUTPUT/STRUCTURE: + OUTPUT_STRUCTURE: true + DISPLACEMENT: true + ELEMENT_OWNER: true + NODE_GID: true + STRESS_STRAIN: true +STRUCTURAL DYNAMIC: + RESTARTEVERY: 25 + DYNAMICTYPE: "Statics" + TIMESTEP: 0.1 + NUMSTEP: 30 + MAXTIME: 3 + TOLDISP: 1e-09 + TOLRES: 1e-09 + ITERNORM: "Inf" + LINEAR_SOLVER: 1 +SOLVER 1: + SOLVER: "UMFPACK" +DESIGN SURF DIRICH CONDITIONS: + - E: 1 + NUMDOF: 3 + ONOFF: [1, 1, 1] + VAL: [0, 0, 0] + FUNCT: [0, 0, 0] +DESIGN SURF NEUMANN CONDITIONS: + - E: 2 + NUMDOF: 3 + ONOFF: [1, 1, 1] + VAL: [10, 10, 10] + FUNCT: [1, 2, 3] +MATERIALS: + - MAT: 1 + MAT_Solid_Superposition: + MATIDS: [11, 12] + DENS: 1.0 + - MAT: 11 + MAT_Struct_StVenantKirchhoff: + YOUNG: 200 + NUE: 0 + DENS: 1 + - MAT: 12 + MAT_Struct_StVenantKirchhoff: + YOUNG: 600 + NUE: 0 + DENS: 1 +FUNCT1: + - COMPONENT: 0 + SYMBOLIC_FUNCTION_OF_SPACE_TIME: "a" + - VARIABLE: 0 + NAME: "a" + TYPE: "linearinterpolation" + NUMPOINTS: 3 + TIMES: [0, 1, 3] + VALUES: [0, 1, 1] +FUNCT2: + - COMPONENT: 0 + SYMBOLIC_FUNCTION_OF_SPACE_TIME: "a" + - VARIABLE: 0 + NAME: "a" + TYPE: "linearinterpolation" + NUMPOINTS: 4 + TIMES: [0, 1, 2, 3] + VALUES: [0, 0, 1, 1] +FUNCT3: + - COMPONENT: 0 + SYMBOLIC_FUNCTION_OF_SPACE_TIME: "a" + - VARIABLE: 0 + NAME: "a" + TYPE: "linearinterpolation" + NUMPOINTS: 3 + TIMES: [0, 2, 3] + VALUES: [0, 0, 1] +RESULT DESCRIPTION: + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "dispx" + VALUE: 0.06338889942814144 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "dispy" + VALUE: 0.0633888994281415 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "dispz" + VALUE: 0.06798864578422244 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "stress_xx" + VALUE: 0.08497433481156066 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "stress_yy" + VALUE: 0.08497433481171451 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "stress_zz" + VALUE: 35.57024088052319 + TOLERANCE: 1e-07 +DNODE-NODE TOPOLOGY: + - "NODE 1 DNODE 1" + - "NODE 9 DNODE 2" + - "NODE 17 DNODE 3" +DSURF-NODE TOPOLOGY: + - "NODE 1 DSURFACE 1" + - "NODE 2 DSURFACE 1" + - "NODE 3 DSURFACE 1" + - "NODE 5 DSURFACE 1" + - "NODE 9 DSURFACE 1" + - "NODE 10 DSURFACE 1" + - "NODE 13 DSURFACE 1" + - "NODE 14 DSURFACE 1" + - "NODE 21 DSURFACE 1" + - "NODE 17 DSURFACE 2" + - "NODE 18 DSURFACE 2" + - "NODE 19 DSURFACE 2" + - "NODE 20 DSURFACE 2" + - "NODE 23 DSURFACE 2" + - "NODE 24 DSURFACE 2" + - "NODE 25 DSURFACE 2" + - "NODE 26 DSURFACE 2" + - "NODE 27 DSURFACE 2" +NODE COORDS: + - "NODE 1 COORD 0.0 0.0 0.0" + - "NODE 2 COORD 0.5 0.0 0.0" + - "NODE 3 COORD 0.0 0.5 0.0" + - "NODE 4 COORD 0.0 0.0 0.5" + - "NODE 5 COORD 0.5 0.5 0.0" + - "NODE 6 COORD 0.5 0.0 0.5" + - "NODE 7 COORD 0.0 0.5 0.5" + - "NODE 8 COORD 0.5 0.5 0.5" + - "NODE 9 COORD 1.0 0.0 0.0" + - "NODE 10 COORD 1.0 0.5 0.0" + - "NODE 11 COORD 1.0 0.0 0.5" + - "NODE 12 COORD 1.0 0.5 0.5" + - "NODE 13 COORD 0.0 1.0 0.0" + - "NODE 14 COORD 0.5 1.0 0.0" + - "NODE 15 COORD 0.0 1.0 0.5" + - "NODE 16 COORD 0.5 1.0 0.5" + - "NODE 17 COORD 0.0 0.0 1.0" + - "NODE 18 COORD 0.5 0.0 1.0" + - "NODE 19 COORD 0.0 0.5 1.0" + - "NODE 20 COORD 0.5 0.5 1.0" + - "NODE 21 COORD 1.0 1.0 0.0" + - "NODE 22 COORD 1.0 1.0 0.5" + - "NODE 23 COORD 1.0 0.0 1.0" + - "NODE 24 COORD 1.0 0.5 1.0" + - "NODE 25 COORD 0.0 1.0 1.0" + - "NODE 26 COORD 0.5 1.0 1.0" + - "NODE 27 COORD 1.0 1.0 1.0" +STRUCTURE ELEMENTS: + - "1 SOLID HEX8 1 2 5 3 4 6 8 7 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "2 SOLID HEX8 2 9 10 5 6 11 12 8 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "3 SOLID HEX8 5 10 21 14 8 12 22 16 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "4 SOLID HEX8 3 5 14 13 7 8 16 15 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "5 SOLID HEX8 4 6 8 7 17 18 20 19 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "6 SOLID HEX8 6 11 12 8 18 23 24 20 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "7 SOLID HEX8 8 12 22 16 20 24 27 26 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "8 SOLID HEX8 7 8 16 15 19 20 26 25 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" diff --git a/tests/input_files/mat_solid_superposition_elasthyper_anisotropic.4C.yaml b/tests/input_files/mat_solid_superposition_elasthyper_anisotropic.4C.yaml new file mode 100644 index 00000000000..c3ee7cb2590 --- /dev/null +++ b/tests/input_files/mat_solid_superposition_elasthyper_anisotropic.4C.yaml @@ -0,0 +1,213 @@ +TITLE: + - Testcase for testing the superposition for 3D solid materials (MAT_Solid_Superposition) using the + elasthyper framework + - The setup of the test-case is a single cube with HEX8 elements. + - The cube is fixed on the bottom surface (z=0). On the top surface (z=1), a surface force is applied + in x-, y- and z-direction subsequently. + - The test uses the MAT_Solid_Superposition with two elasthyper materials. A CoupAnisoExpo (GAMMA 10) + + CoupNeoHooke (YOUNG 15) and a CoupAnisoExpo (GAMMA 25) + CoupNeoHooke (YOUNG 5). + - This is equivalent to a single material with CoupAnisoExpo (GAMMA 35) + CoupNeoHooke (YOUNG 20), verifying + that the anisotropic contributions superpose correctly. +PROBLEM TYPE: + PROBLEMTYPE: "Structure" +IO: + STRUCT_STRESS: "2PK" + STRUCT_STRAIN: "GL" +IO/RUNTIME VTK OUTPUT: + INTERVAL_STEPS: 1 +IO/RUNTIME VTK OUTPUT/STRUCTURE: + OUTPUT_STRUCTURE: true + DISPLACEMENT: true + ELEMENT_OWNER: true + NODE_GID: true + STRESS_STRAIN: true +STRUCTURAL DYNAMIC: + RESTARTEVERY: 25 + DYNAMICTYPE: "Statics" + TIMESTEP: 0.1 + NUMSTEP: 30 + MAXTIME: 3 + TOLDISP: 1e-09 + TOLRES: 1e-09 + ITERNORM: "Inf" + LINEAR_SOLVER: 1 +SOLVER 1: + SOLVER: "UMFPACK" +DESIGN SURF DIRICH CONDITIONS: + - E: 1 + NUMDOF: 3 + ONOFF: [1, 1, 1] + VAL: [0, 0, 0] + FUNCT: [0, 0, 0] +DESIGN SURF NEUMANN CONDITIONS: + - E: 2 + NUMDOF: 3 + ONOFF: [1, 1, 1] + VAL: [10, 10, 10] + FUNCT: [1, 2, 3] +MATERIALS: + - MAT: 1 + MAT_Solid_Superposition: + MATIDS: [10, 20] + DENS: 1.0 + - MAT: 10 + MAT_ElastHyper: + NUMMAT: 2 + MATIDS: [11, 12] + DENS: 1 # note that this density is ignored by the superposition material + - MAT: 11 + ELAST_CoupAnisoExpo: + K1: 100 + K2: 1 + GAMMA: 10 + K1COMP: 0 + K2COMP: 1 + STR_TENS_ID: 1000 + - MAT: 12 + ELAST_CoupNeoHooke: + YOUNG: 15 + NUE: 0.3 + - MAT: 20 + MAT_ElastHyper: + NUMMAT: 2 + MATIDS: [21, 22] + DENS: 1 # note that this density is ignored by the superposition material + - MAT: 21 + ELAST_CoupAnisoExpo: + K1: 100 + K2: 1 + GAMMA: 25 + K1COMP: 0 + K2COMP: 1 + STR_TENS_ID: 1000 + - MAT: 22 + ELAST_CoupNeoHooke: + YOUNG: 5 + NUE: 0.3 + - MAT: 1000 + ELAST_StructuralTensor: + STRATEGY: "Standard" +FUNCT1: + - COMPONENT: 0 + SYMBOLIC_FUNCTION_OF_SPACE_TIME: "a" + - VARIABLE: 0 + NAME: "a" + TYPE: "linearinterpolation" + NUMPOINTS: 3 + TIMES: [0, 1, 3] + VALUES: [0, 1, 1] +FUNCT2: + - COMPONENT: 0 + SYMBOLIC_FUNCTION_OF_SPACE_TIME: "a" + - VARIABLE: 0 + NAME: "a" + TYPE: "linearinterpolation" + NUMPOINTS: 4 + TIMES: [0, 1, 2, 3] + VALUES: [0, 0, 1, 1] +FUNCT3: + - COMPONENT: 0 + SYMBOLIC_FUNCTION_OF_SPACE_TIME: "a" + - VARIABLE: 0 + NAME: "a" + TYPE: "linearinterpolation" + NUMPOINTS: 3 + TIMES: [0, 2, 3] + VALUES: [0, 0, 1] +RESULT DESCRIPTION: + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "dispx" + VALUE: 1.64568384680415725e+00 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "dispy" + VALUE: 1.64568384680415702e+00 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "dispz" + VALUE: 9.35092459998460135e-01 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "stress_xx" + VALUE: 7.66716255631645582e-01 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "stress_yy" + VALUE: 7.66716255631638921e-01 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "stress_zz" + VALUE: 7.11387414277126773e+00 + TOLERANCE: 1e-07 +DNODE-NODE TOPOLOGY: + - "NODE 1 DNODE 1" + - "NODE 9 DNODE 2" + - "NODE 17 DNODE 3" +DSURF-NODE TOPOLOGY: + - "NODE 1 DSURFACE 1" + - "NODE 2 DSURFACE 1" + - "NODE 3 DSURFACE 1" + - "NODE 5 DSURFACE 1" + - "NODE 9 DSURFACE 1" + - "NODE 10 DSURFACE 1" + - "NODE 13 DSURFACE 1" + - "NODE 14 DSURFACE 1" + - "NODE 21 DSURFACE 1" + - "NODE 17 DSURFACE 2" + - "NODE 18 DSURFACE 2" + - "NODE 19 DSURFACE 2" + - "NODE 20 DSURFACE 2" + - "NODE 23 DSURFACE 2" + - "NODE 24 DSURFACE 2" + - "NODE 25 DSURFACE 2" + - "NODE 26 DSURFACE 2" + - "NODE 27 DSURFACE 2" +NODE COORDS: + - "NODE 1 COORD 0.0 0.0 0.0" + - "NODE 2 COORD 0.5 0.0 0.0" + - "NODE 3 COORD 0.0 0.5 0.0" + - "NODE 4 COORD 0.0 0.0 0.5" + - "NODE 5 COORD 0.5 0.5 0.0" + - "NODE 6 COORD 0.5 0.0 0.5" + - "NODE 7 COORD 0.0 0.5 0.5" + - "NODE 8 COORD 0.5 0.5 0.5" + - "NODE 9 COORD 1.0 0.0 0.0" + - "NODE 10 COORD 1.0 0.5 0.0" + - "NODE 11 COORD 1.0 0.0 0.5" + - "NODE 12 COORD 1.0 0.5 0.5" + - "NODE 13 COORD 0.0 1.0 0.0" + - "NODE 14 COORD 0.5 1.0 0.0" + - "NODE 15 COORD 0.0 1.0 0.5" + - "NODE 16 COORD 0.5 1.0 0.5" + - "NODE 17 COORD 0.0 0.0 1.0" + - "NODE 18 COORD 0.5 0.0 1.0" + - "NODE 19 COORD 0.0 0.5 1.0" + - "NODE 20 COORD 0.5 0.5 1.0" + - "NODE 21 COORD 1.0 1.0 0.0" + - "NODE 22 COORD 1.0 1.0 0.5" + - "NODE 23 COORD 1.0 0.0 1.0" + - "NODE 24 COORD 1.0 0.5 1.0" + - "NODE 25 COORD 0.0 1.0 1.0" + - "NODE 26 COORD 0.5 1.0 1.0" + - "NODE 27 COORD 1.0 1.0 1.0" +STRUCTURE ELEMENTS: + - "1 SOLID HEX8 1 2 5 3 4 6 8 7 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "2 SOLID HEX8 2 9 10 5 6 11 12 8 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "3 SOLID HEX8 5 10 21 14 8 12 22 16 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "4 SOLID HEX8 3 5 14 13 7 8 16 15 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "5 SOLID HEX8 4 6 8 7 17 18 20 19 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "6 SOLID HEX8 6 11 12 8 18 23 24 20 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "7 SOLID HEX8 8 12 22 16 20 24 27 26 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "8 SOLID HEX8 7 8 16 15 19 20 26 25 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" diff --git a/tests/input_files/mat_solid_superposition_mixture_anisotropic.4C.yaml b/tests/input_files/mat_solid_superposition_mixture_anisotropic.4C.yaml new file mode 100644 index 00000000000..d11c8d4a58f --- /dev/null +++ b/tests/input_files/mat_solid_superposition_mixture_anisotropic.4C.yaml @@ -0,0 +1,225 @@ +TITLE: + - Testcase for testing the superposition for 3D solid materials (MAT_Solid_Superposition) using a mixture + with anisotropic elasthyper constituents + - The setup of the test-case is a single cube with HEX8 elements. + - The cube is fixed on the bottom surface (z=0). On the top surface (z=1), a surface force is applied + in x-, y- and z-direction subsequently. + - The test uses the MAT_Solid_Superposition with two material constituents. + - A MAT_Mixture (MAT 10) wrapping anisotropic elasthyper materials (ELAST_CoupAnisoExpo GAMMA 10 + ELAST_CoupNeoHooke + YOUNG 15) and a MAT_ElastHyper (MAT 20) with anisotropic elasthyper materials (ELAST_CoupAnisoExpo + GAMMA 25 + ELAST_CoupNeoHooke YOUNG 5). + - MAT 10 contains only a single constituent with mass fraction 1.0, so it acts as a pure wrapper around + the elasthyper material with no actual mixture behavior. This is done to verify that the mixture framework + works correctly within a MAT_Solid_Superposition context. + - The expected results match those of mat_solid_superposition_elasthyper_anisotropic, confirming that + MAT_Solid_Superposition handles mixture constituents correctly." +PROBLEM TYPE: + PROBLEMTYPE: "Structure" +IO: + STRUCT_STRESS: "2PK" + STRUCT_STRAIN: "GL" +IO/RUNTIME VTK OUTPUT: + INTERVAL_STEPS: 1 +IO/RUNTIME VTK OUTPUT/STRUCTURE: + OUTPUT_STRUCTURE: true + DISPLACEMENT: true + ELEMENT_OWNER: true + NODE_GID: true + STRESS_STRAIN: true +STRUCTURAL DYNAMIC: + RESTARTEVERY: 25 + DYNAMICTYPE: "Statics" + TIMESTEP: 0.1 + NUMSTEP: 30 + MAXTIME: 3 + TOLDISP: 1e-09 + TOLRES: 1e-09 + ITERNORM: "Inf" + LINEAR_SOLVER: 1 +SOLVER 1: + SOLVER: "UMFPACK" +DESIGN SURF DIRICH CONDITIONS: + - E: 1 + NUMDOF: 3 + ONOFF: [1, 1, 1] + VAL: [0, 0, 0] + FUNCT: [0, 0, 0] +DESIGN SURF NEUMANN CONDITIONS: + - E: 2 + NUMDOF: 3 + ONOFF: [1, 1, 1] + VAL: [10, 10, 10] + FUNCT: [1, 2, 3] +MATERIALS: + - MAT: 1 + MAT_Solid_Superposition: + MATIDS: [10, 20] + DENS: 1.0 + - MAT: 10 + MAT_Mixture: + MATIDMIXTURERULE: 30 + MATIDSCONST: [40] + - MAT: 30 + MIX_Rule_Simple: + DENS: 1.0 # note that this density is ignored by the superposition material + MASSFRAC: + constant: [1.0] + - MAT: 40 + MIX_Constituent_ElastHyper: + MATIDS: [11, 12] + - MAT: 11 + ELAST_CoupAnisoExpo: + K1: 100 + K2: 1 + GAMMA: 10 + K1COMP: 0 + K2COMP: 1 + STR_TENS_ID: 1000 + - MAT: 12 + ELAST_CoupNeoHooke: + YOUNG: 15 + NUE: 0.3 + - MAT: 20 + MAT_ElastHyper: + NUMMAT: 2 + MATIDS: [21, 22] + DENS: 1 # note that this density is ignored by the superposition material + - MAT: 21 + ELAST_CoupAnisoExpo: + K1: 100 + K2: 1 + GAMMA: 25 + K1COMP: 0 + K2COMP: 1 + STR_TENS_ID: 1000 + - MAT: 22 + ELAST_CoupNeoHooke: + YOUNG: 5 + NUE: 0.3 + - MAT: 1000 + ELAST_StructuralTensor: + STRATEGY: "Standard" +FUNCT1: + - COMPONENT: 0 + SYMBOLIC_FUNCTION_OF_SPACE_TIME: "a" + - VARIABLE: 0 + NAME: "a" + TYPE: "linearinterpolation" + NUMPOINTS: 3 + TIMES: [0, 1, 3] + VALUES: [0, 1, 1] +FUNCT2: + - COMPONENT: 0 + SYMBOLIC_FUNCTION_OF_SPACE_TIME: "a" + - VARIABLE: 0 + NAME: "a" + TYPE: "linearinterpolation" + NUMPOINTS: 4 + TIMES: [0, 1, 2, 3] + VALUES: [0, 0, 1, 1] +FUNCT3: + - COMPONENT: 0 + SYMBOLIC_FUNCTION_OF_SPACE_TIME: "a" + - VARIABLE: 0 + NAME: "a" + TYPE: "linearinterpolation" + NUMPOINTS: 3 + TIMES: [0, 2, 3] + VALUES: [0, 0, 1] +RESULT DESCRIPTION: + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "dispx" + VALUE: 1.64568384680415725e+00 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "dispy" + VALUE: 1.64568384680415702e+00 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "dispz" + VALUE: 9.35092459998460135e-01 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "stress_xx" + VALUE: 7.66716255631645582e-01 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "stress_yy" + VALUE: 7.66716255631638921e-01 + TOLERANCE: 1e-07 + - STRUCTURE: + DIS: "structure" + NODE: 17 + QUANTITY: "stress_zz" + VALUE: 7.11387414277126773e+00 + TOLERANCE: 1e-07 +DNODE-NODE TOPOLOGY: + - "NODE 1 DNODE 1" + - "NODE 9 DNODE 2" + - "NODE 17 DNODE 3" +DSURF-NODE TOPOLOGY: + - "NODE 1 DSURFACE 1" + - "NODE 2 DSURFACE 1" + - "NODE 3 DSURFACE 1" + - "NODE 5 DSURFACE 1" + - "NODE 9 DSURFACE 1" + - "NODE 10 DSURFACE 1" + - "NODE 13 DSURFACE 1" + - "NODE 14 DSURFACE 1" + - "NODE 21 DSURFACE 1" + - "NODE 17 DSURFACE 2" + - "NODE 18 DSURFACE 2" + - "NODE 19 DSURFACE 2" + - "NODE 20 DSURFACE 2" + - "NODE 23 DSURFACE 2" + - "NODE 24 DSURFACE 2" + - "NODE 25 DSURFACE 2" + - "NODE 26 DSURFACE 2" + - "NODE 27 DSURFACE 2" +NODE COORDS: + - "NODE 1 COORD 0.0 0.0 0.0" + - "NODE 2 COORD 0.5 0.0 0.0" + - "NODE 3 COORD 0.0 0.5 0.0" + - "NODE 4 COORD 0.0 0.0 0.5" + - "NODE 5 COORD 0.5 0.5 0.0" + - "NODE 6 COORD 0.5 0.0 0.5" + - "NODE 7 COORD 0.0 0.5 0.5" + - "NODE 8 COORD 0.5 0.5 0.5" + - "NODE 9 COORD 1.0 0.0 0.0" + - "NODE 10 COORD 1.0 0.5 0.0" + - "NODE 11 COORD 1.0 0.0 0.5" + - "NODE 12 COORD 1.0 0.5 0.5" + - "NODE 13 COORD 0.0 1.0 0.0" + - "NODE 14 COORD 0.5 1.0 0.0" + - "NODE 15 COORD 0.0 1.0 0.5" + - "NODE 16 COORD 0.5 1.0 0.5" + - "NODE 17 COORD 0.0 0.0 1.0" + - "NODE 18 COORD 0.5 0.0 1.0" + - "NODE 19 COORD 0.0 0.5 1.0" + - "NODE 20 COORD 0.5 0.5 1.0" + - "NODE 21 COORD 1.0 1.0 0.0" + - "NODE 22 COORD 1.0 1.0 0.5" + - "NODE 23 COORD 1.0 0.0 1.0" + - "NODE 24 COORD 1.0 0.5 1.0" + - "NODE 25 COORD 0.0 1.0 1.0" + - "NODE 26 COORD 0.5 1.0 1.0" + - "NODE 27 COORD 1.0 1.0 1.0" +STRUCTURE ELEMENTS: + - "1 SOLID HEX8 1 2 5 3 4 6 8 7 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "2 SOLID HEX8 2 9 10 5 6 11 12 8 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "3 SOLID HEX8 5 10 21 14 8 12 22 16 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "4 SOLID HEX8 3 5 14 13 7 8 16 15 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "5 SOLID HEX8 4 6 8 7 17 18 20 19 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "6 SOLID HEX8 6 11 12 8 18 23 24 20 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "7 SOLID HEX8 8 12 22 16 20 24 27 26 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" + - "8 SOLID HEX8 7 8 16 15 19 20 26 25 MAT 1 KINEM nonlinear FIBER1 1.0 0.0 0.0" diff --git a/tests/list_of_tests.cmake b/tests/list_of_tests.cmake index 851d5240350..66a9153178a 100644 --- a/tests/list_of_tests.cmake +++ b/tests/list_of_tests.cmake @@ -135,6 +135,8 @@ four_c_test(TEST_FILE beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapp __four_c_test_add_csv_yaml_comparison(BASED_ON ${current} RESULT_FILE xxx-101_monitor_dbc.csv REFERENCE_FILE ref/beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy_dbc_monitor_101.csv TOL_R 0.0 TOL_A 1e-10) four_c_test(TEST_FILE beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy.4C.yaml NP 2 RETURN_AS current) __four_c_test_add_csv_yaml_comparison(BASED_ON ${current} RESULT_FILE xxx-101_monitor_dbc.csv REFERENCE_FILE ref/beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy_dbc_monitor_101.csv TOL_R 0.0 TOL_A 1e-10) +four_c_test(TEST_FILE beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy_red_func_pol5.4C.yaml NP 2) +four_c_test(TEST_FILE beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy_red_func_pol7.4C.yaml NP 2) four_c_test(TEST_FILE beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy_two_half_pass.4C.yaml NP 1 RETURN_AS current) __four_c_test_add_csv_yaml_comparison(BASED_ON ${current} RESULT_FILE xxx-101_monitor_dbc.csv REFERENCE_FILE ref/beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy_two_half_pass/beams-101_monitor_dbc.csv TOL_R 0.0 TOL_A 1e-10) __four_c_test_add_csv_yaml_comparison(BASED_ON ${current} RESULT_FILE xxx-102_monitor_dbc.csv REFERENCE_FILE ref/beam3r_herm2line3_static_vdW_singlelengthsspec_smallsepapprox_simple_end_point_potential_reduction_strategy_two_half_pass/beams-102_monitor_dbc.csv TOL_R 0.0 TOL_A 1e-10) @@ -899,6 +901,10 @@ four_c_test(TEST_FILE mat_humphreycardio.4C.yaml NP 2) four_c_test(TEST_FILE mat_iso_viscoplast_refJC_log_timint.4C.yaml RETURN_AS current) __four_c_test_restart(BASED_ON ${current} SAME_FILE RESTART_STEP 90) four_c_test(TEST_FILE mat_iso_viscoplast_refJC_log_timint_substepping.4C.yaml RETURN_AS current) +four_c_test(TEST_FILE mat_iso_thermoviscoplast_refJC_log_timint_tsi_monolithic.4C.yaml RETURN_AS current) +__four_c_test_restart(BASED_ON ${current} SAME_FILE RESTART_STEP 90) +four_c_test(TEST_FILE mat_iso_thermoviscoplast_refJC_log_timint_tsi_partitioned.4C.yaml RETURN_AS current) +__four_c_test_restart(BASED_ON ${current} SAME_FILE RESTART_STEP 90) four_c_test(TEST_FILE mat_muscle_combo_hex.4C.yaml NP 2 RETURN_AS current) __four_c_test_restart(BASED_ON ${current} SAME_FILE NP 2 RESTART_STEP 140) four_c_test(TEST_FILE mat_muscle_combo_hex_act_map_every_timestep.4C.yaml NP 2 RETURN_AS current) @@ -909,6 +915,12 @@ four_c_test(TEST_FILE mat_muscle_giantesio_hex.4C.yaml NP 2 RETURN_AS current) __four_c_test_restart(BASED_ON ${current} SAME_FILE NP 2 RESTART_STEP 140) four_c_test(TEST_FILE mat_muscle_weickenmeier_hex.4C.yaml NP 2 RETURN_AS current) __four_c_test_restart(BASED_ON ${current} SAME_FILE NP 2 RESTART_STEP 140) +four_c_test(TEST_FILE mat_solid_superposition.4C.yaml NP 2 RETURN_AS current) +__four_c_test_restart(BASED_ON ${current} SAME_FILE NP 2 RESTART_STEP 25) +four_c_test(TEST_FILE mat_solid_superposition_elasthyper_anisotropic.4C.yaml NP 2 RETURN_AS current) +__four_c_test_restart(BASED_ON ${current} SAME_FILE NP 2 RESTART_STEP 25) +four_c_test(TEST_FILE mat_solid_superposition_mixture_anisotropic.4C.yaml NP 2 RETURN_AS current) +__four_c_test_restart(BASED_ON ${current} SAME_FILE NP 2 RESTART_STEP 25) four_c_test(TEST_FILE mat_transversely_isotropic.4C.yaml) four_c_test(TEST_FILE mat_transviso_viscoplast_refJC_log_timint.4C.yaml RETURN_AS current) __four_c_test_restart(BASED_ON ${current} SAME_FILE RESTART_STEP 90) diff --git a/tests/tutorials/battery/tutorial_battery.4C.yaml b/tests/tutorials/battery/tutorial_battery.4C.yaml index 977828503ab..ad846c77765 100644 --- a/tests/tutorials/battery/tutorial_battery.4C.yaml +++ b/tests/tutorials/battery/tutorial_battery.4C.yaml @@ -4,6 +4,7 @@ PROBLEM TYPE: IO: STRUCT_STRESS: "Cauchy" STDOUTEVERY: 0 + ELEMENT_MAT_ID: true IO/RUNTIME VTK OUTPUT: INTERVAL_STEPS: 1 @@ -15,8 +16,8 @@ IO/RUNTIME VTK OUTPUT/STRUCTURE: SSI CONTROL: NUMSTEP: 2 - MAXTIME: 2e+07 - TIMESTEP: 1000 + MAXTIME: 2.0e7 + TIMESTEP: 10.0e3 COUPALGO: ssi_Monolithic SCATRATIMINTTYPE: "Elch" @@ -61,7 +62,7 @@ SCALAR TRANSPORT DYNAMIC/S2I COUPLING: MESHTYING_CONDITIONS_INDEPENDENT_SETUP: true SOLVER 1: - SOLVER: "UMFPACK" + SOLVER: MUMPS MATERIALS: - MAT: 1 @@ -73,6 +74,7 @@ MATERIALS: OCP_MODEL: Function: OCP_FUNCT_NUM: 6 + - MAT: 2 MAT_MultiplicativeSplitDefgradElastHyper: NUMMATEL: 1 @@ -80,10 +82,12 @@ MATERIALS: NUMFACINEL: 1 INELDEFGRADFACIDS: [4] DENS: 4780 + - MAT: 3 ELAST_CoupNeoHooke: YOUNG: 1.8485e+11 NUE: 0.3 + - MAT: 4 MAT_InelasticDefgradPolyIntercalFracIso: SCALAR1: 1 @@ -94,18 +98,21 @@ MATERIALS: X_min: 0.152 X_max: 0.94 MATID: 1 + - MAT: 5 MAT_elchmat: NUMDOF: 2 NUMSCAL: 1 NUMPHASE: 1 PHASEIDS: [6] + - MAT: 6 MAT_elchphase: EPSILON: 1 TORTUOSITY: 1 NUMMAT: 1 MATIDS: [7] + - MAT: 7 MAT_newman: VALENCE: 1 @@ -113,6 +120,7 @@ MATERIALS: COND: 16.11 TRANSFERENCE_NR: 1.0 THERM_FAC: 1.0 + - MAT: 8 MAT_MultiplicativeSplitDefgradElastHyper: NUMMATEL: 1 @@ -120,12 +128,15 @@ MATERIALS: NUMFACINEL: 1 INELDEFGRADFACIDS: [10] DENS: 1850 + - MAT: 9 ELAST_CoupNeoHooke: YOUNG: 2.601e+10 NUE: 0.27 + - MAT: 10 MAT_InelasticDefgradNoGrowth: {} + - MAT: 11 MAT_electrode: DIFF_COEF: 1.0 @@ -135,6 +146,7 @@ MATERIALS: OCP_MODEL: Function: OCP_FUNCT_NUM: 7 + - MAT: 12 MAT_MultiplicativeSplitDefgradElastHyper: NUMMATEL: 1 @@ -142,16 +154,19 @@ MATERIALS: NUMFACINEL: 1 INELDEFGRADFACIDS: [14] DENS: 530 + - MAT: 13 ELAST_CoupNeoHooke: YOUNG: 4.9e+09 NUE: 0.42 + - MAT: 14 MAT_InelasticDefgradLinScalarAniso: SCALAR1: 1 SCALAR1_MolarGrowthFac: 1.2998e-05 SCALAR1_RefConc: 1 GrowthDirection: [1, 0, 0] + - MAT: 15 MAT_electrode: DIFF_COEF: 1.0 @@ -161,6 +176,7 @@ MATERIALS: OCP_MODEL: Function: OCP_FUNCT_NUM: 7 + - MAT: 16 MAT_MultiplicativeSplitDefgradElastHyper: NUMMATEL: 1 @@ -168,10 +184,12 @@ MATERIALS: NUMFACINEL: 1 INELDEFGRADFACIDS: [10] DENS: 8920 + - MAT: 17 ELAST_CoupNeoHooke: YOUNG: 1.15e+11 NUE: 0.34 + - MAT: 19 MAT_electrode: DIFF_COEF: 1.0 @@ -181,6 +199,7 @@ MATERIALS: OCP_MODEL: Function: OCP_FUNCT_NUM: 7 + - MAT: 20 MAT_MultiplicativeSplitDefgradElastHyper: NUMMATEL: 1 @@ -188,6 +207,7 @@ MATERIALS: NUMFACINEL: 1 INELDEFGRADFACIDS: [10] DENS: 2700 + - MAT: 21 ELAST_CoupNeoHooke: YOUNG: 6.9e+10 @@ -198,18 +218,22 @@ CLONING MATERIAL MAP: SRC_MAT: 2 TAR_FIELD: "scatra" TAR_MAT: 1 + - SRC_FIELD: "structure" SRC_MAT: 8 TAR_FIELD: "scatra" TAR_MAT: 5 + - SRC_FIELD: "structure" SRC_MAT: 12 TAR_FIELD: "scatra" TAR_MAT: 11 + - SRC_FIELD: "structure" SRC_MAT: 16 TAR_FIELD: "scatra" TAR_MAT: 15 + - SRC_FIELD: "structure" SRC_MAT: 20 TAR_FIELD: "scatra" @@ -253,198 +277,206 @@ FUNCT6: FUNCT7: - FASTPOLYNOMIAL: NUMCOEFF: 1 - COEFF: [0] + COEFF: [0.0] RESULT DESCRIPTION: - SCATRA: DIS: "scatra" NODE: 32 QUANTITY: "phi1" - VALUE: 1.26777850815654229e+01 - TOLERANCE: 1.3e-07 + VALUE: 1.17729179835590955e+02 + TOLERANCE: 1.2e-06 - SCATRA: DIS: "scatra" NODE: 32 QUANTITY: "phi2" - VALUE: 5.63408408249148287e-06 + VALUE: 5.63420877183655170e-06 TOLERANCE: 5.6e-14 - SCATRA: DIS: "scatra" NODE: 95 QUANTITY: "phi1" - VALUE: 1.2e3 + VALUE: 1.20023216963911113e+03 TOLERANCE: 1.2e-05 - SCATRA: DIS: "scatra" NODE: 95 QUANTITY: "phi2" - VALUE: 1.93918473648069017e-04 - TOLERANCE: 1.9e-12 + VALUE: 2.02652764799278619e-04 + TOLERANCE: 2.0e-12 - SCATRA: DIS: "scatra" NODE: 232 QUANTITY: "phi1" - VALUE: 4.18389051248949399e+04 - TOLERANCE: 4.2e-4 + VALUE: 4.31876698510277783e+04 + TOLERANCE: 4.3e-4 - SCATRA: DIS: "scatra" NODE: 232 QUANTITY: "phi2" - VALUE: 3.60022131383473765e+00 + VALUE: 3.60019943891482708e+00 TOLERANCE: 3.6e-08 - STRUCTURE: DIS: "structure" NODE: 32 QUANTITY: "dispx" - VALUE: -6.66773032761887734e-08 - TOLERANCE: 6.7e-15 + VALUE: 8.44280151667777646e-08 + TOLERANCE: 8.4e-16 - STRUCTURE: DIS: "structure" NODE: 32 QUANTITY: "dispy" - VALUE: -2.07081933892450716e-10 - TOLERANCE: 1.0e-16 + VALUE: -8.44280151749625117e-08 + TOLERANCE: 8.4e-16 - STRUCTURE: DIS: "structure" NODE: 32 QUANTITY: "dispz" - VALUE: 2.07081926671139049e-10 - TOLERANCE: 1.0e-16 + VALUE: -9.67592544354235016e-08 + TOLERANCE: 9.7e-16 - STRUCTURE: DIS: "structure" NODE: 95 QUANTITY: "dispx" - VALUE: -2.46786207653848376e-08 - TOLERANCE: 2.5e-16 + VALUE: 2.07719538778803939e-09 + TOLERANCE: 1.0e-16 - STRUCTURE: DIS: "structure" NODE: 95 QUANTITY: "dispy" - VALUE: 5.06484398044960120e-09 + VALUE: -8.12085065370041722e-09 TOLERANCE: 1.0e-16 - STRUCTURE: DIS: "structure" NODE: 95 QUANTITY: "dispz" - VALUE: -5.06484397125480544e-09 - TOLERANCE: 1.0e-16 + VALUE: -1.76358836650572382e-08 + TOLERANCE: 1.8e-16 - STRUCTURE: DIS: "structure" NODE: 232 QUANTITY: "dispx" - VALUE: -1.92532124495455729e-08 - TOLERANCE: 2.0e-16 + VALUE: 3.14013986975288425e-09 + TOLERANCE: 1.0e-16 - STRUCTURE: DIS: "structure" NODE: 232 QUANTITY: "dispz" - VALUE: 3.77494081961681657e-08 - TOLERANCE: 3.8e-16 + VALUE: -7.04564778319423031e-08 + TOLERANCE: 7.0e-16 PROBLEM SIZE: DIM: 3 DESIGN SURF TRANSPORT NEUMANN CONDITIONS: - - E: 12 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: surface_normal_z_cat_cc NUMDOF: 2 ONOFF: [0, 1] VAL: [0, 5.839316572e-06] - FUNCT: [0, 0] + FUNCT: [null, null] DESIGN POINT DIRICH CONDITIONS: - - E: 23 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: vertices_an_side_cc NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 24 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: vertices_cat_side_cc NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] DESIGN LINE DIRICH CONDITIONS: - - E: 16 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: curves_y_dir_an_cc NUMDOF: 3 ONOFF: [1, 0, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 17 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: curves_x_dir_an_cc NUMDOF: 3 - ONOFF: [1, 1, 0] + ONOFF: [0, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 18 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: curves_(-1_1_0)_dir_an_cc NUMDOF: 3 - ONOFF: [1, 1, 0] + ONOFF: [1, 0, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 19 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: curves_y_dir_cat_cc + NUMDOF: 3 + ONOFF: [1, 0, 1] + VAL: [0, 0, 0] + FUNCT: [null, null, null] + + - NODE_SET_NAME: curves_x_dir_cat_cc NUMDOF: 3 ONOFF: [0, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] + - NODE_SET_NAME: curves_(-1_1_0)_dir_cat_cc + NUMDOF: 3 + ONOFF: [1, 0, 1] + VAL: [0, 0, 0] + FUNCT: [null, null, null] + + - NODE_SET_NAME: curves_z_dir + NUMDOF: 3 + ONOFF: [1, 1, 0] + VAL: [0, 0, 0] + FUNCT: [null, null, null] + DESIGN SURF DIRICH CONDITIONS: - - E: 1 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: surface_normal_z_an_cc NUMDOF: 3 - ONOFF: [1, 0, 0] + ONOFF: [0, 0, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 12 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: surface_normal_z_cat_cc NUMDOF: 3 - ONOFF: [1, 0, 0] + ONOFF: [0, 0, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 13 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: surface_normal_y NUMDOF: 3 ONOFF: [0, 1, 0] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 14 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: surface_normal_x NUMDOF: 3 - ONOFF: [0, 0, 1] + ONOFF: [1, 0, 0] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 15 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: surface_normal_(1_1_0) NUMDOF: 3 ONOFF: [0, 1, 0] VAL: [0, 0, 0] FUNCT: [null, null, null] DESIGN SURF TRANSPORT DIRICH CONDITIONS: - - E: 1 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: surface_normal_z_an_cc NUMDOF: 2 ONOFF: [0, 1] VAL: [0, 0] FUNCT: [0, 0] DESIGN VOL TRANSPORT DIRICH CONDITIONS: - - E: 2 - ENTITY_TYPE: element_block_id - NUMDOF: 2 - ONOFF: [1, 0] - VAL: [1200, 0] - FUNCT: [0, 0] - E: 4 ENTITY_TYPE: element_block_id NUMDOF: 2 ONOFF: [1, 0] VAL: [1200, 0] FUNCT: [0, 0] + - E: 5 ENTITY_TYPE: element_block_id NUMDOF: 2 @@ -457,42 +489,49 @@ DESIGN VOL INITIAL FIELD CONDITIONS: ENTITY_TYPE: element_block_id FIELD: "ScaTra" FUNCT: 1 + - E: 2 ENTITY_TYPE: element_block_id FIELD: "ScaTra" FUNCT: 2 + - E: 3 ENTITY_TYPE: element_block_id FIELD: "ScaTra" FUNCT: 3 + - E: 4 ENTITY_TYPE: element_block_id FIELD: "ScaTra" FUNCT: 4 + - E: 5 ENTITY_TYPE: element_block_id FIELD: "ScaTra" FUNCT: 5 DESIGN LINE LOCSYS CONDITIONS: - - E: 18 - ENTITY_TYPE: node_set_id - ROTANGLE: [0.7853981634, 0, 0] + - NODE_SET_NAME: curves_(-1_1_0)_dir_cat_cc + ROTANGLE: [0, 0, -0.7853981634] + FUNCT: [0, 0, 0] + USEUPDATEDNODEPOS: 0 + USECONSISTENTNODENORMAL: 0 + + - NODE_SET_NAME: curves_(-1_1_0)_dir_an_cc + ROTANGLE: [0, 0, -0.7853981634] FUNCT: [0, 0, 0] USEUPDATEDNODEPOS: 0 USECONSISTENTNODENORMAL: 0 DESIGN SURF LOCSYS CONDITIONS: - - E: 15 - ENTITY_TYPE: node_set_id - ROTANGLE: [0.7853981634, 0, 0] + - NODE_SET_NAME: surface_normal_(1_1_0) + ROTANGLE: [0, 0, -0.7853981634] FUNCT: [0, 0, 0] USEUPDATEDNODEPOS: 0 USECONSISTENTNODENORMAL: 0 DESIGN S2I KINETICS SURF CONDITIONS: - - E: 2 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cc_side(s)_an-cc_interface ConditionID: 0 INTERFACE_SIDE: "Slave" KINETIC_MODEL: "ConstantInterfaceResistance" @@ -500,12 +539,12 @@ DESIGN S2I KINETICS SURF CONDITIONS: RESISTANCE: 1e-05 E-: 1 IS_PSEUDO_CONTACT: false - - E: 3 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: an_side(t)_an-cc_interface ConditionID: 0 INTERFACE_SIDE: "Master" - - E: 4 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: an_side(s)_an-el_interface ConditionID: 1 INTERFACE_SIDE: "Slave" KINETIC_MODEL: "Butler-VolmerReduced" @@ -516,16 +555,16 @@ DESIGN S2I KINETICS SURF CONDITIONS: ALPHA_A: 0.5 ALPHA_C: 0.5 IS_PSEUDO_CONTACT: false - - E: 5 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: el_side(t)_an-el_interface ConditionID: 1 INTERFACE_SIDE: "Master" - - E: 6 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: el_side(t)_cat-el_interface ConditionID: 2 INTERFACE_SIDE: "Master" - - E: 7 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: cat_side(s)_cat-el_interface ConditionID: 2 INTERFACE_SIDE: "Slave" KINETIC_MODEL: "Butler-Volmer" @@ -536,12 +575,12 @@ DESIGN S2I KINETICS SURF CONDITIONS: ALPHA_A: 0.5 ALPHA_C: 0.5 IS_PSEUDO_CONTACT: false - - E: 8 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: cat_side(t)_cat-cc_interface ConditionID: 3 INTERFACE_SIDE: "Master" - - E: 9 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: cc_side(s)_am_cat-cc_interface ConditionID: 3 INTERFACE_SIDE: "Slave" KINETIC_MODEL: "ConstantInterfaceResistance" @@ -549,12 +588,12 @@ DESIGN S2I KINETICS SURF CONDITIONS: RESISTANCE: 1e-05 E-: 1 IS_PSEUDO_CONTACT: false - - E: 10 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: el_side(t)_el_cat-cc_interface ConditionID: 4 INTERFACE_SIDE: "Master" - - E: 11 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: cc_side(s)_el_cat-cc_interface ConditionID: 4 INTERFACE_SIDE: "Slave" KINETIC_MODEL: "NoInterfaceFlux" @@ -568,61 +607,59 @@ DESIGN ELECTRODE STATE OF CHARGE VOL CONDITIONS: ONE_HOUR: 3.6e+06 DESIGN CELL VOLTAGE SURF CONDITIONS: - - E: 1 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: surface_normal_z_an_cc ConditionID: 0 - - E: 12 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: surface_normal_z_cat_cc ConditionID: 1 DESIGN SSI INTERFACE MESHTYING SURF CONDITIONS: - - E: 2 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cc_side(s)_an-cc_interface ConditionID: 0 INTERFACE_SIDE: "Slave" S2I_KINETICS_ID: 0 - - E: 3 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: an_side(t)_an-cc_interface ConditionID: 0 INTERFACE_SIDE: "Master" S2I_KINETICS_ID: 0 - - E: 4 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: an_side(s)_an-el_interface ConditionID: 1 INTERFACE_SIDE: "Slave" S2I_KINETICS_ID: 1 - - E: 5 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: el_side(t)_an-el_interface ConditionID: 1 INTERFACE_SIDE: "Master" S2I_KINETICS_ID: 1 - - E: 6 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: el_side(t)_cat-el_interface ConditionID: 2 INTERFACE_SIDE: "Master" S2I_KINETICS_ID: 2 - - E: 7 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: cat_side(s)_cat-el_interface ConditionID: 2 INTERFACE_SIDE: "Slave" S2I_KINETICS_ID: 2 - - E: 8 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: cat_side(t)_cat-cc_interface ConditionID: 3 INTERFACE_SIDE: "Master" S2I_KINETICS_ID: 3 - - E: 9 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: cc_side(s)_am_cat-cc_interface ConditionID: 3 INTERFACE_SIDE: "Slave" S2I_KINETICS_ID: 3 - - E: 10 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: el_side(t)_el_cat-cc_interface ConditionID: 4 INTERFACE_SIDE: "Master" S2I_KINETICS_ID: 4 - - E: 11 - ENTITY_TYPE: node_set_id + + - NODE_SET_NAME: cc_side(s)_el_cat-cc_interface ConditionID: 4 INTERFACE_SIDE: "Slave" S2I_KINETICS_ID: 4 @@ -631,31 +668,31 @@ STRUCTURE GEOMETRY: FILE: "tutorial_battery.e" SHOW_INFO: "summary" ELEMENT_BLOCKS: - - ID: 1 + - NAME: anode SOLIDSCATRA: TET4: MAT: 12 KINEM: nonlinear TYPE: ElchElectrode - - ID: 2 + - NAME: electrolyte SOLIDSCATRA: TET4: MAT: 8 KINEM: nonlinear TYPE: ElchDiffCond - - ID: 3 + - NAME: cathode SOLIDSCATRA: TET4: MAT: 2 KINEM: nonlinear TYPE: ElchElectrode - - ID: 4 + - NAME: anode_cc SOLIDSCATRA: TET4: MAT: 16 KINEM: nonlinear TYPE: ElchElectrode - - ID: 5 + - NAME: cathode_cc SOLIDSCATRA: TET4: MAT: 20 diff --git a/tests/tutorials/battery/tutorial_battery.e b/tests/tutorials/battery/tutorial_battery.e index c97c207f0d5..ee955778896 100644 Binary files a/tests/tutorials/battery/tutorial_battery.e and b/tests/tutorials/battery/tutorial_battery.e differ diff --git a/tests/tutorials/battery/tutorial_battery.jou b/tests/tutorials/battery/tutorial_battery.jou index 88c326dcf07..b493c33e3aa 100644 --- a/tests/tutorials/battery/tutorial_battery.jou +++ b/tests/tutorials/battery/tutorial_battery.jou @@ -32,15 +32,15 @@ $ -------------------------- $ | geometry | $ -------------------------- $ anode -create brick x {an} y {2*r*cos(theta/360*PI)} z {2*r*cos(theta/360*PI)} +create brick x {2*r*cos(theta/360*PI)} y {2*r*cos(theta/360*PI)} z {an} compress -move volume 1 x {an/2 + (2*n_c-3)*r*cos(theta/360*PI)+2*r+sep} +move volume 1 z {an/2 + (2*n_c-3)*r*cos(theta/360*PI)+2*r+sep} compress $ electrolyte -create brick x {(n_c-1)*2*r*cos(theta/360*PI)+2*r+sep} y {2*r*cos(theta/360*PI)} z {2*r*cos(theta/360*PI)} +create brick x {2*r*cos(theta/360*PI)} y {2*r*cos(theta/360*PI)} z {(n_c-1)*2*r*cos(theta/360*PI)+2*r+sep} compress -move volume 2 x {(n_c-2)*r*cos(theta/360*PI)+r+sep/2} +move volume 2 z {(n_c-2)*r*cos(theta/360*PI)+r+sep/2} compress $ cathode @@ -48,7 +48,7 @@ $ cathode # {Loop(n_c)} create sphere radius {r} # {if(i>0)} - move volume 4 x {i*2*r*cos(theta/360*PI)} + move volume 4 z {i*2*r*cos(theta/360*PI)} unite volume 3 4 compress # {endif} @@ -58,21 +58,21 @@ compress $ insert one non-connected sphere create sphere radius {r_non_conn} -move volume 4 x {-r*cos(theta/360*PI)} y {-r*cos(theta/360*PI)} z {r*cos(theta/360*PI)} +move volume 4 x {r*cos(theta/360*PI)} y {-r*cos(theta/360*PI)} z {-r*cos(theta/360*PI)} intersect volume 2 4 keep subtract volume 4 from volume 2 volume 5 id 4 $ anode current collector -create brick x {cc_an} y {2*r*cos(theta/360*PI)} z {2*r*cos(theta/360*PI)} +create brick x {2*r*cos(theta/360*PI)} y {2*r*cos(theta/360*PI)} z {cc_an} compress -move volume 5 x {cc_an/2 + an + (2*n_c-3)*r*cos(theta/360*PI)+2*r+sep} +move volume 5 z {cc_an/2 + an + (2*n_c-3)*r*cos(theta/360*PI)+2*r+sep} compress $ cathode current collector -create brick x {cc_cat} y {2*r*cos(theta/360*PI)} z {2*r*cos(theta/360*PI)} +create brick x {2*r*cos(theta/360*PI)} y {2*r*cos(theta/360*PI)} z {cc_cat} compress -move volume 6 x {-cc_cat/2-r*cos(theta/360*PI)} +move volume 6 z {-cc_cat/2-r*cos(theta/360*PI)} $ trim the connected cathode spheres to the box size and cut those spheres from the electrolyte intersect volume 2 3 keep @@ -81,14 +81,14 @@ volume 7 id 3 compress $ cut out symmetric cuboid -webcut volume all with plane zplane imprint +webcut volume all with plane xplane imprint delete volume 7 8 9 10 11 compress webcut volume all with plane yplane imprint delete volume 7 8 9 10 11 compress $ cut out symmetric wedge -webcut volume all with plane yplane rotate 45 about x imprint +webcut volume all with plane yplane rotate -45 about z imprint delete volume 7 8 9 10 11 12 compress @@ -109,25 +109,23 @@ set tetmesher optimize level 3 overconstrained off sliver off set tetmesher boundary recovery off volume 1 size {meshsize_a*r} # {if(interfacemeshsize_a>0.0)} - surface with x_max = {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep} in volume 1 size {interfacemeshsize_a} + surface with z_max = {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep} in volume 1 size {interfacemeshsize_a} # {endif} volume 2 size {meshsize_e*r} volume 3 size {meshsize_c*r} # {if(interfacemeshsize_c>0.0)} - surface with not is_plane in volume 3 size {interfacemeshsize_c} -# {endif} -# {if(contactcurveintervals_e>0 && (matching!=1 || (interfacemeshsize_a==0.0 && interfacemeshsize_c==0.0)))} - curve with length <= {2*PI*r*sin(theta/360*PI)} and with Y_Min == Y_Max in volume 2 interval {contactcurveintervals_e} + surface with not is_plane in volume 3 size {interfacemeshsize_c*r} + surface with not is_plane in volume 4 size {interfacemeshsize_c*r} # {endif} # {if(particlediameterintervals_c>0)} curve with Y_Min == 0 and Y_Max == 0 in volume 3 interval {n_c*particlediameterintervals_c} scheme equal # {endif} volume 4 size {meshsize_cat_non*r} -volume 5 size {meshsize_cc_an} -volume 6 size {meshsize_cc_cat} +volume 5 size {meshsize_cc_an*r} +volume 6 size {meshsize_cc_cat*r} mesh volume all # {if(meshrefinements_a>0)} - refine surface with x_max = {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep} in volume 1 numsplit {meshrefinements_a} bias 1.0 depth 1 smooth + refine surface with z_max = {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep} in volume 1 numsplit {meshrefinements_a} bias 1.0 depth 1 smooth # {endif} # {if(meshrefinements_c>0)} refine surface with not is_plane in volume 3 numsplit {meshrefinements_c} bias 1.0 depth 1 smooth @@ -156,130 +154,139 @@ block 3 Name "cathode" # anode side current collector block 4 volume 5 -block 4 Name "anode cc" +block 4 Name "anode_cc" # cathode side current collector block 5 volume 6 -block 5 Name "cathode cc" +block 5 Name "cathode_cc" # anode-side current collector -nodeset 1 surface with x_min >= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+cc_an-tol} in volume 5 -nodeset 1 Name "an-side cc" +nodeset 1 surface with z_min >= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+cc_an-tol} in volume 5 +nodeset 1 Name "surface_normal_z_an_cc" # current collector-side of anode-current collector interface -nodeset 2 surface with x_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+tol} in volume 5 -nodeset 2 Name "cc-side (sl) of an-cc interface" +nodeset 2 surface with z_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+tol} in volume 5 +nodeset 2 Name "cc_side(s)_an-cc_interface" # anode-side of anode-current collector interface -nodeset 3 surface with x_min >= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an-tol} in volume 1 -nodeset 3 Name "an-side (ma) of an-cc interface" +nodeset 3 surface with z_min >= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an-tol} in volume 1 +nodeset 3 Name "an_side(t)_an-cc_interface" # anode-side of anode-electrolyte interface -nodeset 4 surface with x_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+tol} in volume 1 -nodeset 4 Name "an-side (sl) of an-el interface" +nodeset 4 surface with z_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+tol} in volume 1 +nodeset 4 Name "an_side(s)_an-el_interface" # electrolyte-side of anode-electrolyte interface -nodeset 5 surface with x_min >= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep-tol} in volume 2 -nodeset 5 Name "el-side (ma) of an-el interface" +nodeset 5 surface with z_min >= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep-tol} in volume 2 +nodeset 5 Name "el_side(t)_an-el_interface" # electrolyte-side of cathode-electrolyte interface nodeset 6 surface with not is_plane in volume 2 -nodeset 6 Name "el-side (ma) of cat-el interface" +nodeset 6 Name "el_side(t)_cat-el_interface" # cathode-side of cathode-electrolyte interface nodeset 7 surface with not is_plane in volume 3 4 -#nodeset 7 Name "cat-side (sl) of cat-el interface" #commented since string is too long for the tutorial-framework, yet it is good to have descriptive names +nodeset 7 Name "cat_side(s)_cat-el_interface" # cathode-side of composite cathode-current collector interface -nodeset 8 surface with x_max <= {-r*cos(theta/360*PI) + tol} in volume 3 4 -#nodeset 8 Name "cat-side (ma) of cat-cc interface" #commented since string is too long for the tutorial-framework, yet it is good to have descriptive names +nodeset 8 surface with z_max <= {-r*cos(theta/360*PI) + tol} in volume 3 4 +nodeset 8 Name "cat_side(t)_cat-cc_interface" # current collector-side of cathode part composite cathode-current collector interface -nodeset 9 surface with x_min >= {-r*cos(theta/360*PI) - tol} and z_max <= {0.5*r*cos(theta/360*PI)} in volume 6 -nodeset 9 surface with x_min >= {-r*cos(theta/360*PI) - tol} and z_min >= {0.5*r*cos(theta/360*PI)} in volume 6 -#nodeset 9 Name "cc-side (sl) of cat-comp_cat-cc interface" #commented since string is too long for the tutorial-framework, yet it is good to have descriptive names +nodeset 9 surface with z_min >= {-r*cos(theta/360*PI) - tol} and x_max <= {r*sin(theta/360*PI)*cos(45/180*PI)+tol} in volume 6 +nodeset 9 surface with z_min >= {-r*cos(theta/360*PI) - tol} and x_min >= {r*cos(theta/360*PI)-r_non_conn-tol} in volume 6 +nodeset 9 Name "cc_side(s)_am_cat-cc_interface" # solid electrolyte-side of composite cathode-current collector interface -nodeset 10 surface with x_max <= {-r*cos(theta/360*PI) + tol} in volume 2 -#nodeset 10 Name "sol-el-side (ma) of comp_cat-cc interface" #commented since string is too long for the tutorial-framework, yet it is good to have descriptive names +nodeset 10 surface with z_max <= {-r*cos(theta/360*PI) + tol} in volume 2 +nodeset 10 Name "el_side(t)_el_cat-cc_interface" # current collector-side of cathode part composite cathode-current collector interface -nodeset 11 surface with x_min >= {-r*cos(theta/360*PI) - tol} and z_min <= {0.5*r*cos(theta/360*PI)} and z_max >= {0.5*r*cos(theta/360*PI)} in volume 6 -#nodeset 11 Name "cc-side (sl) of sol-el-comp_cat-cc interface" #commented since string is too long for the tutorial-framework, yet it is good to have descriptive names +nodeset 11 surface with z_min >= {-r*cos(theta/360*PI) - tol} and x_min == {0.0} and x_max >= {r*sin(theta/360*PI)*sin(45/180*PI) + tol} in volume 6 +nodeset 11 Name "cc_side(s)_el_cat-cc_interface" # cathode-side current collector -nodeset 12 surface with x_max <= {-r*cos(theta/360*PI)-cc_cat} in volume 6 -nodeset 12 Name "cat-side cc" +nodeset 12 surface with z_max <= {-r*cos(theta/360*PI)-cc_cat+tol} in volume 6 +nodeset 12 Name "surface_normal_z_cat_cc" # battery surface normal to y axis # add all surfaces that are normal to the y axis -nodeset 13 surface with y_max <= {-r*cos(theta/360*PI)} in volume all -# remove lines of cathode and anode as they are the slave side nodes -> no DBC can be prescribed here +nodeset 13 surface with y_max <= {-r*cos(theta/360*PI)+tol} in volume all +# remove lines of cathode and anode as they are the source side nodes -> no DBC can be prescribed here nodeset 13 node in surface with not is_plane in volume 3 4 remove -nodeset 13 node in surface with x_min >= {-r*cos(theta/360*PI)-tol} in volume 6 remove -nodeset 13 node in surface with x_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+tol} in volume 5 remove -nodeset 13 node in surface with x_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+tol} in volume 1 remove -nodeset 13 Name "battery surface normal to y" - -# battery surface normal to z axis -# add all surfaces that are normal to the z axis -nodeset 14 surface with z_max <= {0.0} in volume all -# remove lines of cathode and anode as they are the slave side nodes -> no DBC can be prescribed here +nodeset 13 node in surface with z_min >= {-r*cos(theta/360*PI)-tol} in volume 6 remove +nodeset 13 node in surface with z_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+tol} in volume 5 remove +nodeset 13 node in surface with z_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+tol} in volume 1 remove +nodeset 13 Name "surface_normal_y" + +# battery surface normal to x axis +# add all surfaces that are normal to the x axis +nodeset 14 surface with x_max <= {tol} in volume all +# remove lines of cathode and anode as they are the source side nodes -> no DBC can be prescribed here nodeset 14 node in surface with not is_plane in volume 3 4 remove -nodeset 14 node in surface with x_min >= {-r*cos(theta/360*PI)-tol} in volume 6 remove -nodeset 14 node in surface with x_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+tol} in volume 5 remove -nodeset 14 node in surface with x_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+tol} in volume 1 remove -nodeset 14 Name "battery surface normal to z" - -# battery surface which normal vector is (0 1 1) -# add surfaces that are normal to (0 1 1) - vector of volume 1 -nodeset 15 surface with ((x_max - x_min > {an-tol} ) && (y_max - y_min > {0.7071*r*cos(theta/360*PI)} ) && (z_max - z_min > {0.7071*r*cos(theta/360*PI)} )) in volume 1 -# add surfaces that are normal to (0 1 1) - vector of volume 2 & 3 -nodeset 15 surface with ((x_max - x_min > {r+(2*n_c - 1)*r*cos(theta/360*PI) - tol} ) && (y_max - y_min > {0.7071*r*cos(theta/360*PI)} ) && (z_max - z_min > {0.7071*r*cos(theta/360*PI)} ) && is_plane ) in volume 2 & 3 -# add surfaces that are normal to (0 1 1) - vector of volume 4 -nodeset 15 surface with (x_max - x_min > {r_non_conn - tol} ) && y_max > {-r*cos(theta/360*PI) + tol} && is_plane in volume 4 -# add surfaces that are normal to (0 1 1) - vector of volume 5 -nodeset 15 surface with ((x_max - x_min > {cc_an-tol} ) && (y_max - y_min > {0.7071*r*cos(theta/360*PI)} ) && (z_max - z_min > {0.7071*r*cos(theta/360*PI)} )) in volume 5 -# add surfaces that are normal to (0 1 1) - vector of volume 6 -nodeset 15 surface with ((x_max - x_min > {cc_cat-tol} ) && (y_max - y_min > {0.7071*r*cos(theta/360*PI)} ) && (z_max - z_min > {0.7071*r*cos(theta/360*PI)} )) in volume 6 -# remove lines of cathode and anode as they are the slave side nodes -> no DBC can be prescribed here -nodeset 15 node in surface with not is_plane in volume 3 4 remove -nodeset 15 node in surface with x_min >= {-r*cos(theta/360*PI)-tol} in volume 6 remove -nodeset 15 node in surface with x_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+tol} in volume 5 remove -nodeset 15 node in surface with x_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+tol} in volume 1 remove -#nodeset 15 Name "battery surface normal to (0 1 1) vector" #commented since string is too long for the tutorial-framework, yet it is good to have descriptive names - -# lines in y-direction that need a DBC -nodeset 16 curve with (((x_max - x_min) < {tol}) && ((z_max - z_min) < {tol}) && (x_max <= {-r*cos(theta/360*PI)-cc_cat})) in volume 6 -nodeset 16 curve with (((x_max - x_min) < {tol}) && ((z_max - z_min) < {tol}) && (x_min >= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+cc_an-tol})) in volume 5 -nodeset 16 Name "battery curves in y-direction" - -# lines in z-direction that need a DBC -nodeset 17 curve with (((x_max - x_min) < {tol}) && ((y_max - y_min) < {tol}) && (x_max <= {-r*cos(theta/360*PI)-cc_cat})) in volume 6 -nodeset 17 curve with (((x_max - x_min) < {tol}) && ((y_max - y_min) < {tol}) && (x_min >= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+cc_an-tol})) in volume 5 -nodeset 17 Name "battery curves in z-direction" - -# all lines in (0 1 -1) direction that need a DBC -nodeset 18 curve with ((y_max - y_min) > {tol} && (z_max - z_min) > {tol} && (x_min >= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+cc_an-tol})) in volume 5 -nodeset 18 curve with ((y_max - y_min) > {tol} && (z_max - z_min) > {tol} && (x_max <= {-r*cos(theta/360*PI)-cc_cat})) in volume 6 -#nodeset 18 Name "battery curves in (0 1 -1)-direction" #commented since string is too long for the tutorial-framework, yet it is good to have descriptive names - -# all lines at the battery edges in x-direction -nodeset 19 curve with ((y_max == y_min) && (z_max == z_min)) in volume all -# remove slave side nodes -nodeset 19 node in surface with not is_plane in volume 3 4 remove -nodeset 19 node in surface with x_min >= {-r*cos(theta/360*PI)-tol} in volume 6 remove -nodeset 19 node in surface with x_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+tol} in volume 5 remove -nodeset 19 node in surface with x_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+tol} in volume 1 remove -nodeset 19 Name "battery curves in x-direction" +nodeset 14 node in surface with z_min >= {-r*cos(theta/360*PI)-tol} in volume 6 remove +nodeset 14 node in surface with z_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+tol} in volume 5 remove +nodeset 14 node in surface with z_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+tol} in volume 1 remove +nodeset 14 Name "surface_normal_x" + +# lines in y-direction at cathode-side current collector +nodeset 15 curve with (((z_max - z_min) < {tol}) and ((x_max - x_min) < {tol}) and (z_max <= {-r*cos(theta/360*PI)-cc_cat+tol})) in volume 6 +nodeset 15 Name "curves_y_dir_cat_cc" + +# lines in x-direction at cathode-side current collector +nodeset 16 curve with (((z_max - z_min) < {tol}) and ((y_max - y_min) < {tol}) and (z_max <= {-r*cos(theta/360*PI)-cc_cat+tol})) in volume 6 +nodeset 16 Name "curves_x_dir_cat_cc" + +# all lines at the battery edges in z-direction +nodeset 17 curve with (((x_max - x_min) < {tol}) and ((y_max - y_min) < {tol})) in volume all +# remove source side nodes +nodeset 17 node in surface with not is_plane in volume 3 4 remove +nodeset 17 node in surface with z_min >= {-r*cos(theta/360*PI)-tol} in volume 6 remove +nodeset 17 node in surface with z_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+tol} in volume 5 remove +nodeset 17 node in surface with z_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+tol} in volume 1 remove +nodeset 17 Name "curves_z_dir" + +# lines in y-direction at anode-side current collector +nodeset 18 curve with (((z_max - z_min) < {tol}) and ((x_max - x_min) < {tol}) and (z_min >= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+cc_an-tol})) in volume 5 +nodeset 18 Name "curves_y_dir_an_cc" + +# lines in x-direction at anode-side current collector +nodeset 19 curve with (((z_max - z_min) < {tol}) and ((y_max - y_min) < {tol}) and (z_min >= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+cc_an-tol})) in volume 5 +nodeset 19 Name "curves_x_dir_an_cc" # all vertices at anode-side current collector -nodeset 23 vertex in surface with x_min >= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+cc_an-tol} in volume 5 -nodeset 23 Name "vertices an-side cc +nodeset 20 vertex in surface with z_min >= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+cc_an-tol} in volume 5 +nodeset 20 Name "vertices_an_side_cc" # all vertices at the cathode-side current collector -nodeset 24 vertex in surface with x_max <= {-r*cos(theta/360*PI)-cc_cat} in volume 6 -nodeset 24 Name "vertices cat-side cc" +nodeset 21 vertex in surface with z_max <= {-r*cos(theta/360*PI)-cc_cat+tol} in volume 6 +nodeset 21 Name "vertices_cat_side_cc" + +# battery surface which normal vector is (1 1 0) +# add surfaces that are normal to (1 1 0) - vector of volume 1 +nodeset 22 surface with ((z_max - z_min > {an-tol} ) and (y_max - y_min > {0.7071*r*cos(theta/360*PI)} ) and (x_max - x_min > {0.7071*r*cos(theta/360*PI)} )) in volume 1 +# add surfaces that are normal to (1 1 0) - vector of volume 2 & 3 +nodeset 22 surface with ((z_max - z_min > {r+(2*n_c - 1)*r*cos(theta/360*PI) - tol} ) and (y_max - y_min > {0.7071*r*cos(theta/360*PI)} ) and (x_max - x_min > {0.7071*r*cos(theta/360*PI)} ) and is_plane ) in volume 2 3 +# add surfaces that are normal to (1 1 0) - vector of volume 4 +nodeset 22 surface with (z_max - z_min > {r_non_conn - tol} ) and y_max > {-r*cos(theta/360*PI) + tol} and is_plane in volume 4 +# add surfaces that are normal to (1 1 0) - vector of volume 5 +nodeset 22 surface with ((z_max - z_min > {cc_an-tol} ) and (y_max - y_min > {0.7071*r*cos(theta/360*PI)} ) and (x_max - x_min > {0.7071*r*cos(theta/360*PI)} )) in volume 5 +# add surfaces that are normal to (1 1 0) - vector of volume 6 +nodeset 22 surface with ((z_max - z_min > {cc_cat-tol} ) and (y_max - y_min > {0.7071*r*cos(theta/360*PI)} ) and (x_max - x_min > {0.7071*r*cos(theta/360*PI)} )) in volume 6 +# remove lines of cathode and anode as they are the source side nodes -> no DBC can be prescribed here +nodeset 22 node in surface with not is_plane in volume 3 4 remove +nodeset 22 node in surface with z_min >= {-r*cos(theta/360*PI)-tol} in volume 6 remove +nodeset 22 node in surface with z_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+tol} in volume 5 remove +nodeset 22 node in surface with z_max <= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+tol} in volume 1 remove +nodeset 22 Name "surface_normal_(1_1_0)" + +# lines in (-1 1 0) direction at cathode-side current collector +nodeset 23 curve with ((y_max - y_min) > {tol} and (x_max - x_min) > {tol} and (z_max <= {-r*cos(theta/360*PI)-cc_cat+tol})) in volume 6 +nodeset 23 Name "curves_(-1_1_0)_dir_cat_cc" + +# lines in (-1 1 0) direction at anode-side current collector +nodeset 24 curve with ((y_max - y_min) > {tol} and (x_max - x_min) > {tol} and (z_min >= {(2*n_c-3)*r*cos(theta/360*PI)+2*r+sep+an+cc_an-tol})) in volume 5 +nodeset 24 Name "curves_(-1_1_0)_dir_an_cc" $ -------------------------- $ | scaling | @@ -289,5 +296,5 @@ volume all scale {scaling} $ -------------------------- $ | export | $ -------------------------- -export genesis "tutorial_battery.e" block all dimension 3 overwrite +export mesh "tutorial_battery.e" dimension 3 overwrite exit diff --git a/tests/tutorials/fsi/tutorial_fsi_2d.4C.yaml b/tests/tutorials/fsi/tutorial_fsi_2d.4C.yaml index 8eaca9db877..74dde5e62a0 100644 --- a/tests/tutorials/fsi/tutorial_fsi_2d.4C.yaml +++ b/tests/tutorials/fsi/tutorial_fsi_2d.4C.yaml @@ -142,85 +142,71 @@ FLUID GEOMETRY: NA: ALE DESIGN POINT DIRICH CONDITIONS: - - E: 3 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: structure_vertices NUMDOF: 2 ONOFF: [1, 1] VAL: [0, 0] FUNCT: [0, 0] - - E: 4 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: structure_fsi_vertices NUMDOF: 2 ONOFF: [1, 1] VAL: [0, 0] FUNCT: [0, 0] - - E: 10 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: inflow_vertices_top NUMDOF: 3 ONOFF: [1, 1, 0] VAL: [1, 0, 0] FUNCT: [1, 0, 0] - - E: 11 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_vertices NUMDOF: 3 ONOFF: [1, 1, 0] VAL: [0, 0, 0] FUNCT: [0, 0, 0] - - E: 12 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: fluid_fsi_vertices NUMDOF: 3 ONOFF: [1, 1, 0] VAL: [0, 0, 0] FUNCT: [0, 0, 0] DESIGN LINE DIRICH CONDITIONS: - - E: 1 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: structure_clamping_curves NUMDOF: 2 ONOFF: [1, 1] VAL: [0, 0] FUNCT: [0, 0] - - E: 5 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_wall_curves NUMDOF: 3 ONOFF: [1, 1, 0] VAL: [0, 0, 0] FUNCT: [0, 0, 0] - - E: 6 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: inflow_volume_curve_top NUMDOF: 3 ONOFF: [1, 1, 0] VAL: [1, 0, 0] FUNCT: [1, 0, 0] - - E: 7 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: inflow_area_curve NUMDOF: 3 ONOFF: [1, 1, 0] VAL: [1, 0, 0] FUNCT: [2, 0, 0] DESIGN POINT ALE DIRICH CONDITIONS: - - E: 13 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: fluid_vertices_all NUMDOF: 2 ONOFF: [1, 1] VAL: [0, 0] FUNCT: [0, 0] DESIGN LINE ALE DIRICH CONDITIONS: - - E: 6 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: inflow_volume_curve_top NUMDOF: 2 ONOFF: [1, 1] VAL: [0, 0] FUNCT: [0, 0] - - E: 8 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: fluid_curves_in_y-direction NUMDOF: 2 ONOFF: [1, 1] VAL: [0, 0] FUNCT: [0, 0] DESIGN FSI COUPLING LINE CONDITIONS: - - E: 2 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: structure_fsi_curve coupling_id: 1 - - E: 9 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: fluid_fsi_curve coupling_id: 1 diff --git a/tests/tutorials/fsi/tutorial_fsi_2d.e b/tests/tutorials/fsi/tutorial_fsi_2d.e index abd53d8d42b..42d5c260927 100644 Binary files a/tests/tutorials/fsi/tutorial_fsi_2d.e and b/tests/tutorials/fsi/tutorial_fsi_2d.e differ diff --git a/tests/tutorials/fsi/tutorial_fsi_2d.jou b/tests/tutorials/fsi/tutorial_fsi_2d.jou index 49a341b228a..2e3881417e5 100644 --- a/tests/tutorials/fsi/tutorial_fsi_2d.jou +++ b/tests/tutorials/fsi/tutorial_fsi_2d.jou @@ -199,15 +199,15 @@ block 1 name "flexible_bottom" $ curves nodeset 1 curve in structure_ycurves -nodeset 1 name "structure clamping curves" +nodeset 1 name "structure_clamping_curves" nodeset 2 curve in group structure_fsi_xcurves -nodeset 2 name "structure fsi curve" +nodeset 2 name "structure_fsi_curve" $ vertices nodeset 3 vertex in group structure_vertex -nodeset 3 name "structure vertices" +nodeset 3 name "structure_vertices" nodeset 4 vertex in group structure_vertex_fsi -nodeset 4 name "structure fsi vertices" +nodeset 4 name "structure_fsi_vertices" $======================= Fluid $ surfaces @@ -216,25 +216,25 @@ block 2 name "fluid" $ curves nodeset 5 curve in group cavity_ycurves -nodeset 5 name "cavity wall curves" +nodeset 5 name "cavity_wall_curves" nodeset 6 curve in group inflow_vol_xcurves_top -nodeset 6 name "inflow volume curve top" +nodeset 6 name "inflow_volume_curve_top" nodeset 7 curve in group inflow_ycurves -nodeset 7 name "inflow area curve" +nodeset 7 name "inflow_area_curve" nodeset 8 curve in group fluid_ycurves -nodeset 8 name "fluid curves in y-direction" +nodeset 8 name "fluid_curves_in_y-direction" nodeset 9 curve in group cavity_fsi_xcurves -nodeset 9 name "fluid fsi curve" +nodeset 9 name "fluid_fsi_curve" $ vertices nodeset 10 vertex in group inflow_vertex_top -nodeset 10 name "inflow vertices top" +nodeset 10 name "inflow_vertices_top" nodeset 11 vertex in group cavity_vertex -nodeset 11 name "cavity vertices" +nodeset 11 name "cavity_vertices" nodeset 12 vertex in group fluid_vertex_fsi -nodeset 12 name "fluid fsi vertices" +nodeset 12 name "fluid_fsi_vertices" nodeset 13 vertex in group fluid_vertex -nodeset 13 name "fluid vertices all" +nodeset 13 name "fluid_vertices_all" $======================= export mesh -export mesh "tutorial_fsi.e" block all dimension 2 overwrite +export mesh "tutorial_fsi_2d.e" block all dimension 2 overwrite diff --git a/tests/tutorials/fsi/tutorial_fsi_3d.4C.yaml b/tests/tutorials/fsi/tutorial_fsi_3d.4C.yaml index b8c7c0b6985..d758c102360 100644 --- a/tests/tutorials/fsi/tutorial_fsi_3d.4C.yaml +++ b/tests/tutorials/fsi/tutorial_fsi_3d.4C.yaml @@ -105,369 +105,308 @@ FLUID GEOMETRY: NA: ALE DESIGN POINT DIRICH CONDITIONS: - - E: 32 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_vertex_front_left_bottom NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 33 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_vertex_back_left_bottom NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 34 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_vertex_back_right_bottom NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 35 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_vertex_front_right_bottom NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 36 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity-inflow_vertex_front_1 NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 36 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity-inflow_vertex_front_1 NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 38 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: lid_vertex_front_left NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [1, 0, 0, 0] FUNCT: [1, null, null, null] - - E: 39 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: lid_vertex_back_left NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [1, 0, 0, 0] FUNCT: [1, null, null, null] DESIGN LINE DIRICH CONDITIONS: - - E: 6 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: structure_edge_front_left NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 7 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: structure_edge_back_left NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 8 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: structure_edge_back_right NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 9 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: structure_edge_front_right NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 18 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_edge_front_left NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 19 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_edge_back_left NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 20 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_edge_back_right NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 21 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_edge_front_right NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 22 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_edge_front_bottom NUMDOF: 4 ONOFF: [0, 0, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 23 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_edge_back_bottom NUMDOF: 4 ONOFF: [0, 0, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 24 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_edge_left_bottom NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 25 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_edge_right_bottom NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 26 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity-inflow_edge NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 27 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: inflow_edge_front NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [1, 0, 0, 0] FUNCT: [2, null, null, null] - - E: 28 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: inflow_edge_back NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [1, 0, 0, 0] FUNCT: [2, null, null, null] - - E: 29 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: lid_edge_left NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [1, 0, 0, 0] FUNCT: [1, null, null, null] - - E: 30 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: lid_edge_front NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [1, 0, 0, 0] FUNCT: [1, null, null, null] - - E: 31 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: lid_edge_back NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [1, 0, 0, 0] FUNCT: [1, null, null, null] DESIGN SURF DIRICH CONDITIONS: - - E: 1 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: structure_surface_left NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 2 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: structure_surface_right NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 3 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: structure_surface_front NUMDOF: 3 ONOFF: [0, 0, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 4 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: structure_surface_back NUMDOF: 3 ONOFF: [0, 0, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 10 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_wall_left NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 11 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_wall_right NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 12 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: fluid_wall_front NUMDOF: 4 ONOFF: [0, 0, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 13 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: fluid_wall_back NUMDOF: 4 ONOFF: [0, 0, 1, 0] VAL: [0, 0, 0, 0] FUNCT: [null, null, null, null] - - E: 15 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: lid NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [1, 0, 0, 0] FUNCT: [1, null, null, null] - - E: 16 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: inflow NUMDOF: 4 ONOFF: [1, 1, 1, 0] VAL: [1, 0, 0, 0] FUNCT: [2, null, null, null] DESIGN POINT ALE DIRICH CONDITIONS: - - E: 36 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity-inflow_vertex_front_1 NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 37 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity-inflow_vertex_front_2 NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 38 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: lid_vertex_front_left NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 39 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: lid_vertex_back_left NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] DESIGN LINE ALE DIRICH CONDITIONS: - - E: 18 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_edge_front_left NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 19 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_edge_back_left NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 20 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_edge_back_right NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 21 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_edge_front_right NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 24 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_edge_left_bottom NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 25 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_edge_right_bottom NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 26 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity-inflow_edge NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 27 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: inflow_edge_front NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 28 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: inflow_edge_back NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 29 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: lid_edge_left NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 30 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: lid_edge_front NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 31 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: lid_edge_back NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] DESIGN SURF ALE DIRICH CONDITIONS: - - E: 10 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_wall_left NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 11 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: cavity_wall_right NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 12 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: fluid_wall_front NUMDOF: 3 ONOFF: [0, 0, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 13 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: fluid_wall_back NUMDOF: 3 ONOFF: [0, 0, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 15 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: lid NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 16 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: inflow NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] - - E: 17 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: outflow NUMDOF: 3 ONOFF: [1, 1, 1] VAL: [0, 0, 0] FUNCT: [null, null, null] DESIGN FSI COUPLING SURF CONDITIONS: - - E: 5 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: structure_coupling_surface coupling_id: 1 - - E: 14 - ENTITY_TYPE: node_set_id + - NODE_SET_NAME: fluid_coupling_surface coupling_id: 1 diff --git a/tests/tutorials/fsi/tutorial_fsi_3d.e b/tests/tutorials/fsi/tutorial_fsi_3d.e index 376ddba1199..8d64ec0e809 100644 Binary files a/tests/tutorials/fsi/tutorial_fsi_3d.e and b/tests/tutorials/fsi/tutorial_fsi_3d.e differ diff --git a/tests/tutorials/fsi/tutorial_fsi_3d.jou b/tests/tutorials/fsi/tutorial_fsi_3d.jou index 31344d856e8..43cc66a4bf5 100644 --- a/tests/tutorials/fsi/tutorial_fsi_3d.jou +++ b/tests/tutorials/fsi/tutorial_fsi_3d.jou @@ -54,36 +54,36 @@ $=======================Structure block 1 volume 1 block 1 name "flexible bottom" nodeset 1 surface 4 -nodeset 1 name "structure surface left" +nodeset 1 name "structure_surface_left" nodeset 2 surface 6 -nodeset 2 name "structure surface right" +nodeset 2 name "structure_surface_right" nodeset 3 surface 1 -nodeset 3 name "structure surface front" +nodeset 3 name "structure_surface_front" nodeset 4 surface 2 -nodeset 4 name "structure surface back" +nodeset 4 name "structure_surface_back" nodeset 5 surface 5 -nodeset 5 name "structure coupling surface" +nodeset 5 name "structure_coupling_surface" nodeset 6 curve 3 -nodeset 6 name "structure edge front left" +nodeset 6 name "structure_edge_front_left" nodeset 7 curve 7 -nodeset 7 name "structure edge back left" +nodeset 7 name "structure_edge_back_left" nodeset 8 curve 5 -nodeset 8 name "structure edge back right" +nodeset 8 name "structure_edge_back_right" nodeset 9 curve 1 -nodeset 9 name "structure edge front right" +nodeset 9 name "structure_edge_front_right" $=======================Fluid block 2 volume 2 3 block 2 name "fluid" nodeset 10 surface 15 -nodeset 10 name "cavity wall left" +nodeset 10 name "cavity_wall_left" nodeset 11 surface 17 -nodeset 11 name "cavity wall right" +nodeset 11 name "cavity_wall_right" nodeset 12 surface 14 21 -nodeset 12 name "fluid wall front" +nodeset 12 name "fluid_wall_front" nodeset 13 surface 16 20 -nodeset 13 name "fluid wall back" +nodeset 13 name "fluid_wall_back" nodeset 14 surface 9 -nodeset 14 name "fluid coupling surface" +nodeset 14 name "fluid_coupling_surface" nodeset 15 surface 11 nodeset 15 name "lid" nodeset 16 surface 22 @@ -91,49 +91,49 @@ nodeset 16 name "inflow" nodeset 17 surface 19 nodeset 17 name "outflow" nodeset 18 curve 29 -nodeset 18 name "cavity edge front left" +nodeset 18 name "cavity_edge_front_left" nodeset 19 curve 31 -nodeset 19 name "cavity edge back left" +nodeset 19 name "cavity_edge_back_left" nodeset 20 curve 32 -nodeset 20 name "cavity edge back right" +nodeset 20 name "cavity_edge_back_right" nodeset 21 curve 30 -nodeset 21 name "cavity edge front right" +nodeset 21 name "cavity_edge_front_right" nodeset 22 curve 16 -nodeset 22 name "cavity edge front bottom" +nodeset 22 name "cavity_edge_front_bottom" nodeset 23 curve 18 -nodeset 23 name "cavity edge back bottom" +nodeset 23 name "cavity_edge_back_bottom" nodeset 24 curve 21 -nodeset 24 name "cavity edge left bottom" +nodeset 24 name "cavity_edge_left_bottom" nodeset 25 curve 22 -nodeset 25 name "cavity edge right bottom" +nodeset 25 name "cavity_edge_right_bottom" nodeset 26 curve 26 -nodeset 26 name "cavity-inflow edge" +nodeset 26 name "cavity-inflow_edge" nodeset 27 curve 40 -nodeset 27 name "inflow edge front" +nodeset 27 name "inflow_edge_front" nodeset 28 curve 39 -nodeset 28 name "inflow edge back" +nodeset 28 name "inflow_edge_back" nodeset 29 curve 23 -nodeset 29 name "lid edge left" +nodeset 29 name "lid_edge_left" nodeset 30 curve 14 -nodeset 30 name "lid edge front" +nodeset 30 name "lid_edge_front" nodeset 31 curve 20 -nodeset 31 name "lid edge back" +nodeset 31 name "lid_edge_back" nodeset 32 vertex 12 -nodeset 32 name "cavity vertex front left bottom" +nodeset 32 name "cavity_vertex_front_left_bottom" nodeset 33 vertex 15 -nodeset 33 name "cavity vertex back left bottom" +nodeset 33 name "cavity_vertex_back_left_bottom" nodeset 34 vertex 14 -nodeset 34 name "cavity vertex back right bottom" +nodeset 34 name "cavity_vertex_back_right_bottom" nodeset 35 vertex 9 -nodeset 35 name "cavity vertex front right bottom" +nodeset 35 name "cavity_vertex_front_right_bottom" nodeset 36 vertex 19 -nodeset 36 name "cavity-inflow vertex front 1" +nodeset 36 name "cavity-inflow_vertex_front_1" nodeset 37 vertex 17 -nodeset 37 name "cavity-inflow vertex front 2" +nodeset 37 name "cavity-inflow_vertex_front_2" nodeset 38 vertex 11 -nodeset 38 name "lid vertex front left" +nodeset 38 name "lid_vertex_front_left" nodeset 39 vertex 16 -nodeset 39 name "lid vertex back left" +nodeset 39 name "lid_vertex_back_left" $======================= export mesh export mesh "tutorial_fsi_3d.e" block all dimension 3 overwrite diff --git a/unittests/mat/4C_inelastic_defgrad_factors_service_test.cpp b/unittests/mat/4C_inelastic_defgrad_factors_service_test.cpp new file mode 100644 index 00000000000..a74454452bb --- /dev/null +++ b/unittests/mat/4C_inelastic_defgrad_factors_service_test.cpp @@ -0,0 +1,420 @@ +// This file is part of 4C multiphysics licensed under the +// GNU Lesser General Public License v3.0 or later. +// +// See the LICENSE.md file in the top-level for license information. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include + +#include "4C_linalg_fixedsizematrix.hpp" +#include "4C_mat_inelastic_defgrad_factors_service.hpp" +#include "4C_unittest_utils_assertions_test.hpp" +#include "4C_utils_singleton_owner.hpp" + + +namespace +{ + using namespace FourC; + + namespace ViscoplastUtils = Mat::InelasticDefgradTransvIsotropElastViscoplastUtils; + + class InelasticDefgradFactorsServiceTest : public ::testing::Test + { + protected: + void SetUp() override {} + + + Core::Utils::SingletonOwnerRegistry::ScopeGuard guard; + }; + + /// tests the LocalIntegrationDeformationTensors of + /// InelasticDefgradTransvIsotropElastViscoplast + TEST_F(InelasticDefgradFactorsServiceTest, TestLocalIntegrationDeformationTensors) + { + // setup input + Core::LinAlg::Matrix<3, 3> defgrad{Core::LinAlg::Initialization::zero}; + defgrad(0, 0) = 0.2513819028974873; + defgrad(0, 1) = 0.957511195526664; + defgrad(0, 2) = 0.8703229224151933; + defgrad(1, 0) = 0.675673714544612; + defgrad(1, 1) = 0.040444301498430923; + defgrad(1, 2) = 0.10298502801901921; + defgrad(2, 0) = 0.20079631315327318; + defgrad(2, 1) = 0.6901106554801166; + defgrad(2, 2) = 0.1769124998126297; + + + Core::LinAlg::Matrix<3, 3> last_iFin{Core::LinAlg::Initialization::zero}; + last_iFin(0, 0) = 0.35530729350748047; + last_iFin(0, 1) = 0.5829896953147952; + last_iFin(0, 2) = 0.9336918888091672; + last_iFin(1, 0) = 0.3099852313939162; + last_iFin(1, 1) = 0.7243285059889488; + last_iFin(1, 2) = 0.43375156919140767; + last_iFin(2, 0) = 0.41454463288433163; + last_iFin(2, 1) = 0.6433884759079006; + last_iFin(2, 2) = 0.23890433987101256; + + + // reference tensors based on input + Core::LinAlg::Matrix<3, 3> inv_defgrad_ref{Core::LinAlg::Initialization::zero}; + inv_defgrad_ref(0, 0) = -0.22190619146746082; + inv_defgrad_ref(0, 1) = 1.4971400487822994; + inv_defgrad_ref(0, 2) = 0.2201485775679747; + inv_defgrad_ref(1, 0) = -0.34321290611467375; + inv_defgrad_ref(1, 1) = -0.4523291882409134; + inv_defgrad_ref(1, 2) = 1.951751255286342; + inv_defgrad_ref(2, 0) = 1.590689346533634; + inv_defgrad_ref(2, 1) = 0.06521297552376205; + inv_defgrad_ref(2, 2) = -2.2108633434926004; + + + Core::LinAlg::Matrix<3, 3> right_cg_ref{Core::LinAlg::Initialization::zero}; + right_cg_ref(0, 0) = 0.5600469890068229; + right_cg_ref(0, 1) = 0.40659981309094395; + right_cg_ref(0, 2) = 0.3238910865092303; + right_cg_ref(1, 0) = 0.40659981309094395; + right_cg_ref(1, 1) = 1.3947161478897936; + right_cg_ref(1, 2) = 0.9595983006673772; + right_cg_ref(2, 0) = 0.3238910865092303; + right_cg_ref(2, 1) = 0.9595983006673772; + right_cg_ref(2, 2) = 0.7993659378673543; + + + Core::LinAlg::Matrix<3, 3> elastic_predictor_inverse_plastic_defgrad_ref{ + Core::LinAlg::Initialization::zero}; + elastic_predictor_inverse_plastic_defgrad_ref(0, 0) = 0.35530729350748047; + elastic_predictor_inverse_plastic_defgrad_ref(0, 1) = 0.5829896953147952; + elastic_predictor_inverse_plastic_defgrad_ref(0, 2) = 0.9336918888091672; + elastic_predictor_inverse_plastic_defgrad_ref(1, 0) = 0.3099852313939162; + elastic_predictor_inverse_plastic_defgrad_ref(1, 1) = 0.7243285059889488; + elastic_predictor_inverse_plastic_defgrad_ref(1, 2) = 0.43375156919140767; + elastic_predictor_inverse_plastic_defgrad_ref(2, 0) = 0.41454463288433163; + elastic_predictor_inverse_plastic_defgrad_ref(2, 1) = 0.6433884759079006; + elastic_predictor_inverse_plastic_defgrad_ref(2, 2) = 0.23890433987101256; + + + Core::LinAlg::Matrix<3, 3> elastic_predictor_elastic_defgrad_ref{ + Core::LinAlg::Initialization::zero}; + elastic_predictor_elastic_defgrad_ref(0, 0) = 0.7469198494262896; + elastic_predictor_elastic_defgrad_ref(0, 1) = 1.4000614513018017; + elastic_predictor_elastic_defgrad_ref(0, 2) = 0.8579591505610411; + elastic_predictor_elastic_defgrad_ref(1, 0) = 0.2953008256002754; + elastic_predictor_elastic_defgrad_ref(1, 1) = 0.48946515367319354; + elastic_predictor_elastic_defgrad_ref(1, 2) = 0.6730174161271413; + elastic_predictor_elastic_defgrad_ref(2, 0) = 0.3586066330866571; + elastic_predictor_elastic_defgrad_ref(2, 1) = 0.7307524651000326; + elastic_predictor_elastic_defgrad_ref(2, 2) = 0.5290836326068751; + + // initialize LocalIntegrationDeformationTensors and perform checks for the saved quantities + ViscoplastUtils::LocalIntegrationDeformationTensors deftensors(defgrad, last_iFin); + FOUR_C_EXPECT_NEAR(deftensors.defgrad, defgrad, 1.0e-15); + FOUR_C_EXPECT_NEAR(deftensors.inv_defgrad, inv_defgrad_ref, 1.0e-15); + FOUR_C_EXPECT_NEAR(deftensors.right_cg, right_cg_ref, 1.0e-15); + FOUR_C_EXPECT_NEAR(deftensors.elastic_predictor_elastic_defgrad, + elastic_predictor_elastic_defgrad_ref, 1.0e-15); + FOUR_C_EXPECT_NEAR(deftensors.elastic_predictor_inverse_plastic_defgrad, + elastic_predictor_inverse_plastic_defgrad_ref, 1.0e-15); + } + + + /// tests the bookkeeping of iterations within the LocalNewtonManager of + /// InelasticDefgradTransvIsotropElastViscoplast + TEST_F(InelasticDefgradFactorsServiceTest, TestLocalNewtonManagerIterBookkeeping) + { + auto local_newton_params = + Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonParams{ + .res_tol = 1.0e-8, + .incr_tol = 1.0e-8, + .conv_check = ViscoplastUtils::LocalNewtonConvCheck::residual_and_increment_ratio, + .diver_cont = ViscoplastUtils::LocalNewtonDiverCont::stop, + .max_iter = 5, + .max_exceedance_fact_res_tol = 1.0e1, + .max_exceedance_fact_incr_tol = 1.0e1, + + }; + Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonManager local_newton_manager( + local_newton_params); + + EXPECT_EQ(local_newton_manager.iter(), 0); + EXPECT_EQ(local_newton_manager.curr_num_iters().size(), 1); + EXPECT_EQ(local_newton_manager.curr_num_iters()[0], 0); + + local_newton_manager.resize(3); + EXPECT_EQ(local_newton_manager.curr_num_iters().size(), 3); + EXPECT_EQ(local_newton_manager.curr_num_iters()[0], 0); + EXPECT_EQ(local_newton_manager.curr_num_iters()[1], 0); + EXPECT_EQ(local_newton_manager.curr_num_iters()[2], 0); + + Core::LinAlg::Matrix<10, 1> one_10x1{Core::LinAlg::Initialization::zero}; + for (unsigned int i = 0; i < 10; ++i) one_10x1(i) = 1.0; + + local_newton_manager.reset_iter(); + local_newton_manager.save_init_estimate_and_reset_convergence_quantities(one_10x1); + local_newton_manager.increment_solution_vector(one_10x1); + local_newton_manager.increment_iter(); + local_newton_manager.increment_solution_vector(one_10x1); + local_newton_manager.increment_iter(); + local_newton_manager.increment_solution_vector(one_10x1); + local_newton_manager.increment_iter(); + EXPECT_EQ(local_newton_manager.iter(), 3); + local_newton_manager.update_after_local_newton(1); + EXPECT_EQ(local_newton_manager.curr_num_iters()[1], 3); + + local_newton_manager.save_init_estimate_and_reset_convergence_quantities(one_10x1); + local_newton_manager.increment_solution_vector(one_10x1); + local_newton_manager.increment_iter(); + EXPECT_EQ(local_newton_manager.iter(), 4); + local_newton_manager.update_after_local_newton(1); + EXPECT_EQ(local_newton_manager.curr_num_iters()[1], 7); + + local_newton_manager.reset_curr_num_iters(0); + EXPECT_EQ(local_newton_manager.curr_num_iters()[0], 0); + local_newton_manager.reset_curr_num_iters(1); + EXPECT_EQ(local_newton_manager.curr_num_iters()[1], 0); + local_newton_manager.reset_curr_num_iters(2); + EXPECT_EQ(local_newton_manager.curr_num_iters()[2], 0); + + + // test whether the maximum number of iterations was exceeded + EXPECT_FALSE(local_newton_manager.is_max_iter_reached()); + local_newton_manager.increment_solution_vector(one_10x1); + local_newton_manager.increment_iter(); + local_newton_manager.increment_solution_vector(one_10x1); + local_newton_manager.increment_iter(); + EXPECT_TRUE(local_newton_manager.is_max_iter_reached()); + } + + + /// tests the basic functionality of the LocalNewtonManager (initialization, incrementation, + /// convergence and "stuckness" verification) used within + /// InelasticDefgradTransvIsotropElastViscoplast + TEST_F(InelasticDefgradFactorsServiceTest, TestLocalNewtonManagerBasicFunctionality) + { + auto local_newton_params = + Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonParams{ + .res_tol = 1.0e-8, + .incr_tol = 1.0e-8, + .conv_check = ViscoplastUtils::LocalNewtonConvCheck::residual_and_increment_ratio, + .diver_cont = ViscoplastUtils::LocalNewtonDiverCont::stop, + .max_iter = 100, + .max_exceedance_fact_res_tol = 0.0, + .max_exceedance_fact_incr_tol = 0.0, + }; + Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonManager local_newton_manager( + local_newton_params); + + // auxiliaries + Core::LinAlg::Matrix<10, 1> one_10x1{Core::LinAlg::Initialization::zero}; + for (unsigned int i = 0; i < 10; ++i) one_10x1(i) = 1.0; + + + // --> test initialization with and without iteration counter reset + + // with iteration counter reset + local_newton_manager.reset_iter(); + local_newton_manager.save_init_estimate_and_reset_convergence_quantities(one_10x1); + FOUR_C_EXPECT_NEAR(local_newton_manager.sol(), one_10x1, 1.0e-15); + EXPECT_EQ(local_newton_manager.iter(), 0); + + // without iteration counter reset + local_newton_manager.increment_solution_vector(one_10x1); + local_newton_manager.increment_iter(); // increment the iteration counter + local_newton_manager.save_init_estimate_and_reset_convergence_quantities(one_10x1); + FOUR_C_EXPECT_NEAR(local_newton_manager.sol(), one_10x1, 1.0e-15); + EXPECT_EQ(local_newton_manager.iter(), 1); + + + // --> test workflow within the Local Newton: increment the solution vector (save the + // increment), then set the residual norm, and perform the convergence check + Core::LinAlg::Matrix<10, 1> vector_under_tol{ + Core::LinAlg::Initialization::zero}; // the 2-norm of this vector is smaller than the set + // value for residual and increment tolerance + vector_under_tol(0) = 1.0e-9; + Core::LinAlg::Matrix<10, 1> vector_over_tol{Core::LinAlg::Initialization::zero}; + vector_over_tol(0) = 1.0e-7; // the 2-norm of this vector is smaller than the set value for + // residual and increment tolerance + + Core::LinAlg::Matrix<10, 1> updated_sol_ref( + Core::LinAlg::Initialization::zero); // reference: updated solution vector, used for the + // solution vector checks + + // try out increment and residual vector exceeding the tolerance: no convergence! + local_newton_manager.reset_iter(); + local_newton_manager.save_init_estimate_and_reset_convergence_quantities(one_10x1); + local_newton_manager.increment_solution_vector(vector_over_tol); + local_newton_manager.increment_iter(); + updated_sol_ref.update(1.0, one_10x1, 1.0, vector_over_tol, 0.0); + FOUR_C_EXPECT_NEAR(local_newton_manager.sol(), updated_sol_ref, 1.0e-15); + EXPECT_EQ(local_newton_manager.convergence_quantities().increment_norm, + vector_over_tol(0) / updated_sol_ref.norm2()); + EXPECT_EQ(local_newton_manager.iter(), 1); + local_newton_manager.set_residual_norm(vector_over_tol); + EXPECT_EQ(local_newton_manager.convergence_quantities().residual_norm, vector_over_tol(0)); + EXPECT_FALSE(local_newton_manager.is_local_newton_converged()); + + // try out increment exceeding the tolerance, and residual vector under the tolerance: no + // convergence! + local_newton_manager.increment_solution_vector(vector_over_tol); + local_newton_manager.increment_iter(); + updated_sol_ref.update(1.0, vector_over_tol, 1.0); + FOUR_C_EXPECT_NEAR(local_newton_manager.sol(), updated_sol_ref, 1.0e-15); + EXPECT_EQ(local_newton_manager.convergence_quantities().increment_norm, + vector_over_tol(0) / updated_sol_ref.norm2()); + EXPECT_EQ(local_newton_manager.iter(), 2); + local_newton_manager.set_residual_norm(vector_under_tol); + EXPECT_EQ(local_newton_manager.convergence_quantities().residual_norm, vector_under_tol(0)); + EXPECT_FALSE(local_newton_manager.is_local_newton_converged()); + + // now the other way around: no convergence! + local_newton_manager.increment_solution_vector(vector_under_tol); + local_newton_manager.increment_iter(); + updated_sol_ref.update(1.0, vector_under_tol, 1.0); + FOUR_C_EXPECT_NEAR(local_newton_manager.sol(), updated_sol_ref, 1.0e-15); + EXPECT_EQ(local_newton_manager.convergence_quantities().increment_norm, + vector_under_tol(0) / updated_sol_ref.norm2()); + EXPECT_EQ(local_newton_manager.iter(), 3); + local_newton_manager.set_residual_norm(vector_over_tol); + EXPECT_EQ(local_newton_manager.convergence_quantities().residual_norm, vector_over_tol(0)); + EXPECT_FALSE(local_newton_manager.is_local_newton_converged()); + + // now, both increment and residual are under the tolerance: convergence! + local_newton_manager.increment_solution_vector(vector_under_tol); + local_newton_manager.increment_iter(); + updated_sol_ref.update(1.0, vector_under_tol, 1.0); + FOUR_C_EXPECT_NEAR(local_newton_manager.sol(), updated_sol_ref, 1.0e-15); + EXPECT_EQ(local_newton_manager.convergence_quantities().increment_norm, + vector_under_tol(0) / updated_sol_ref.norm2()); + EXPECT_EQ(local_newton_manager.iter(), 4); + local_newton_manager.set_residual_norm(vector_under_tol); + EXPECT_EQ(local_newton_manager.convergence_quantities().residual_norm, vector_under_tol(0)); + EXPECT_TRUE(local_newton_manager.is_local_newton_converged()); + + // --> test whether the Local Newton becomes stuck: increment is exactly 0.0, but the residual + // is still over the set tolerance + EXPECT_FALSE(local_newton_manager.is_local_newton_stuck()); // for the previous settings, the + // Local Newton should not be stuck + Core::LinAlg::Matrix<10, 1> zero_10x1{Core::LinAlg::Initialization::zero}; + local_newton_manager.increment_solution_vector(zero_10x1); + local_newton_manager.increment_iter(); + FOUR_C_EXPECT_NEAR(local_newton_manager.sol(), updated_sol_ref, 1.0e-15); + EXPECT_EQ(local_newton_manager.convergence_quantities().increment_norm, 0.0); + EXPECT_EQ(local_newton_manager.iter(), 5); + local_newton_manager.set_residual_norm(vector_over_tol); + EXPECT_EQ(local_newton_manager.convergence_quantities().residual_norm, vector_over_tol(0)); + EXPECT_TRUE(local_newton_manager.is_local_newton_stuck()); + } + + + /// tests the convergence of the LocalNewtonManager (for various settings) used within + /// InelasticDefgradTransvIsotropElastViscoplast + TEST_F(InelasticDefgradFactorsServiceTest, TestLocalNewtonManagerConvergenceVerification) + { + // framework for setting up multiple LocalNewtonManager objects with varied parameters + auto local_newton_base_params = + Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonParams{ + .res_tol = 1.0e-8, + .incr_tol = 1.0e-10, + .conv_check = ViscoplastUtils::LocalNewtonConvCheck::residual_and_increment_ratio, + .diver_cont = ViscoplastUtils::LocalNewtonDiverCont::stop, + .max_iter = 100, + .max_exceedance_fact_res_tol = 0.0, + .max_exceedance_fact_incr_tol = 0.0, + }; + auto set_up_local_newton_manager = [local_newton_base_params]( + const ViscoplastUtils::LocalNewtonConvCheck conv_check) + { + Core::LinAlg::Matrix<10, 1> one_10x1{Core::LinAlg::Initialization::zero}; + for (unsigned int i = 0; i < 10; ++i) one_10x1(i) = 1.0; + + auto manager = ViscoplastUtils::LocalNewtonManager({ + .res_tol = local_newton_base_params.res_tol, + .incr_tol = local_newton_base_params.incr_tol, + .conv_check = conv_check, // override + .diver_cont = local_newton_base_params.diver_cont, + .max_iter = local_newton_base_params.max_iter, + .max_exceedance_fact_res_tol = local_newton_base_params.max_exceedance_fact_res_tol, + .max_exceedance_fact_incr_tol = local_newton_base_params.max_exceedance_fact_incr_tol, + }); + manager.reset_iter(); + manager.save_init_estimate_and_reset_convergence_quantities(one_10x1); + + return manager; + }; + + // setup several Local Newton managers + ViscoplastUtils::LocalNewtonManager manager_res_and_incr = set_up_local_newton_manager( + ViscoplastUtils::LocalNewtonConvCheck::residual_and_increment_ratio); + ViscoplastUtils::LocalNewtonManager manager_res = + set_up_local_newton_manager(ViscoplastUtils::LocalNewtonConvCheck::residual); + ViscoplastUtils::LocalNewtonManager manager_incr = + set_up_local_newton_manager(ViscoplastUtils::LocalNewtonConvCheck::increment_ratio); + + // setup vectors (residual / increment) to be used for convergence checks + auto vector_from_tol = [](const double first_value) + { + Core::LinAlg::Matrix<10, 1> out{ + Core::LinAlg::Initialization::zero}; // the 2-norm of this vector is smaller than the set + // value for residual and increment tolerance + out(0) = first_value; + + return out; + }; + + // setup numerical values smaller than, or exceeding the set tolerances + const double exceeds_incr_tol{1.0e-9}; + const double exceeds_res_tol{1.0e-7}; + const double smaller_than_incr_tol{1.0e-10}; + const double smaller_than_res_tol{1.0e-9}; + + + // try out residual and increment exceeding the set tolerances + manager_res_and_incr.increment_solution_vector(vector_from_tol(exceeds_incr_tol)); + manager_res_and_incr.increment_iter(); + manager_res.increment_solution_vector(vector_from_tol(exceeds_incr_tol)); + manager_res.increment_iter(); + manager_incr.increment_solution_vector(vector_from_tol(exceeds_incr_tol)); + manager_incr.increment_iter(); + + manager_res_and_incr.set_residual_norm(vector_from_tol(exceeds_res_tol)); + manager_res.set_residual_norm(vector_from_tol(exceeds_res_tol)); + manager_incr.set_residual_norm(vector_from_tol(exceeds_res_tol)); + + EXPECT_FALSE(manager_res_and_incr.is_local_newton_converged()); + EXPECT_FALSE(manager_res.is_local_newton_converged()); + EXPECT_FALSE(manager_incr.is_local_newton_converged()); + + // try out residual smaller than the set tolerance, with increment exceeding its set tolerance + manager_res_and_incr.increment_solution_vector(vector_from_tol(exceeds_incr_tol)); + manager_res_and_incr.increment_iter(); + manager_res.increment_solution_vector(vector_from_tol(exceeds_incr_tol)); + manager_res.increment_iter(); + manager_incr.increment_solution_vector(vector_from_tol(exceeds_incr_tol)); + manager_incr.increment_iter(); + + manager_res_and_incr.set_residual_norm(vector_from_tol(smaller_than_res_tol)); + manager_res.set_residual_norm(vector_from_tol(smaller_than_res_tol)); + manager_incr.set_residual_norm(vector_from_tol(smaller_than_res_tol)); + + EXPECT_FALSE(manager_res_and_incr.is_local_newton_converged()); + EXPECT_TRUE(manager_res.is_local_newton_converged()); + EXPECT_FALSE(manager_incr.is_local_newton_converged()); + + // try out residual exceeding its set tolerance, with increment smaller than its set tolerance + manager_res_and_incr.increment_solution_vector(vector_from_tol(smaller_than_incr_tol)); + manager_res_and_incr.increment_iter(); + manager_res.increment_solution_vector(vector_from_tol(smaller_than_incr_tol)); + manager_res.increment_iter(); + manager_incr.increment_solution_vector(vector_from_tol(smaller_than_incr_tol)); + manager_incr.increment_iter(); + + manager_res_and_incr.set_residual_norm(vector_from_tol(exceeds_res_tol)); + manager_res.set_residual_norm(vector_from_tol(exceeds_res_tol)); + manager_incr.set_residual_norm(vector_from_tol(exceeds_res_tol)); + + EXPECT_FALSE(manager_res_and_incr.is_local_newton_converged()); + EXPECT_FALSE(manager_res.is_local_newton_converged()); + EXPECT_TRUE(manager_incr.is_local_newton_converged()); + } +} // namespace diff --git a/unittests/mat/4C_inelastic_defgrad_factors_test.cpp b/unittests/mat/4C_inelastic_defgrad_factors_test.cpp index b06cf1fc20d..6b4fa61b4aa 100644 --- a/unittests/mat/4C_inelastic_defgrad_factors_test.cpp +++ b/unittests/mat/4C_inelastic_defgrad_factors_test.cpp @@ -168,17 +168,26 @@ namespace material_data.group("LOCAL_SUBSTEPPING").add("USE_SUBSTEPPING", setup.use_substepping); material_data.group("LOCAL_SUBSTEPPING") .add("MAX_SUBSTEPPING_HALVE_NUM", static_cast(setup.max_substepping_halve_num)); - material_data.group("LOCAL_NEWTON").add("CONV_CHECK", setup.local_newton_params.conv_check); - material_data.group("LOCAL_NEWTON").add("DIVER_CONT", setup.local_newton_params.diver_cont); - material_data.group("LOCAL_NEWTON").add("INCR_TOL", setup.local_newton_params.incr_tol); - material_data.group("LOCAL_NEWTON").add("RES_TOL", setup.local_newton_params.res_tol); - material_data.group("LOCAL_NEWTON") - .add("MAX_ITER", static_cast(setup.local_newton_params.max_iter)); - material_data.group("LOCAL_NEWTON") - .add("MAX_EXCEEDANCE_FACT_RES_TOL", setup.local_newton_params.max_exceedance_fact_res_tol); - material_data.group("LOCAL_NEWTON") - .add( - "MAX_EXCEEDANCE_FACT_INCR_TOL", setup.local_newton_params.max_exceedance_fact_incr_tol); + const auto local_newton_params = + Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonParams{ + .res_tol = setup.local_newton_params.res_tol, + .incr_tol = setup.local_newton_params.incr_tol, + .conv_check = setup.local_newton_params.conv_check, + .diver_cont = setup.local_newton_params.diver_cont, + .max_iter = setup.local_newton_params.max_iter, + .max_exceedance_fact_res_tol = setup.local_newton_params.max_exceedance_fact_res_tol, + .max_exceedance_fact_incr_tol = setup.local_newton_params.max_exceedance_fact_incr_tol, + }; + material_data.add("LOCAL_NEWTON", local_newton_params); + const auto error_registration_settings = + Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorRegistrationSettings{ + .register_plastic_strain_incr_overflow = true, + .max_plastic_strain_incr = std::exp(30.0), + .register_plastic_strain_deriv_incr_overflow = false, + .max_plastic_strain_deriv_incr = std::exp(30.0)}; + material_data.add("ERROR_REGISTRATION_SETTINGS", error_registration_settings); + + auto material_params = std::dynamic_pointer_cast( @@ -229,7 +238,7 @@ namespace Core::Materials::MaterialType::mvl_reformulated_Johnson_Cook, viscoplastic_law_data)); auto viscoplastic_law = std::make_shared( - problem.materials()->parameter_by_id(viscoplastic_law_id)); + problem.materials()->parameter_by_id(viscoplastic_law_id), error_registration_settings); std::vector> pot_sum_el; pot_sum_el.emplace_back(Mat::Elastic::Summand::factory(200)); @@ -1797,52 +1806,6 @@ namespace computed_state_quantities_isotrop.curr_lpM, 1.0e-10); } - TEST_F(InelasticDefgradFactorsTest, TestLocalNewtonParametersParsing) - { - const auto local_newton_params = set_up_viscoplastic_material().params->local_newton_params(); - - EXPECT_EQ(local_newton_params.conv_check, - Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonConvCheck:: - residual_and_increment_ratio); - EXPECT_EQ(local_newton_params.diver_cont, - Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonDiverCont::stop); - EXPECT_EQ(local_newton_params.max_iter, 100); - EXPECT_DOUBLE_EQ(local_newton_params.res_tol, 1.0e-8); - EXPECT_DOUBLE_EQ(local_newton_params.incr_tol, 1.0e-8); - EXPECT_DOUBLE_EQ(local_newton_params.max_exceedance_fact_res_tol, 1.0e1); - EXPECT_DOUBLE_EQ(local_newton_params.max_exceedance_fact_incr_tol, 1.0e1); - } - - TEST_F(InelasticDefgradFactorsTest, TestLocalNewtonManagerBookkeeping) - { - const auto material = set_up_viscoplastic_material(); - Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonManager local_newton_manager( - material.params->local_newton_params()); - - EXPECT_EQ(local_newton_manager.iter(), 0); - EXPECT_EQ(local_newton_manager.curr_num_iters().size(), 1); - EXPECT_EQ(local_newton_manager.curr_num_iters()[0], 0); - - local_newton_manager.resize(3); - EXPECT_EQ(local_newton_manager.curr_num_iters().size(), 3); - EXPECT_EQ(local_newton_manager.curr_num_iters()[0], 0); - EXPECT_EQ(local_newton_manager.curr_num_iters()[1], 0); - EXPECT_EQ(local_newton_manager.curr_num_iters()[2], 0); - - local_newton_manager.set_iteration_count(4); - local_newton_manager.update_after_local_newton(1); - EXPECT_EQ(local_newton_manager.curr_num_iters()[1], 4); - - local_newton_manager.set_iteration_count(2); - local_newton_manager.update_after_local_newton(1); - EXPECT_EQ(local_newton_manager.curr_num_iters()[1], 6); - - local_newton_manager.reset(); - EXPECT_EQ(local_newton_manager.curr_num_iters()[0], 0); - EXPECT_EQ(local_newton_manager.curr_num_iters()[1], 0); - EXPECT_EQ(local_newton_manager.curr_num_iters()[2], 0); - } - TEST_F(InelasticDefgradFactorsTest, TestLocalNewtonDivergenceHandlingStop) { Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::LocalNewtonParams local_newton_params{ @@ -1880,7 +1843,9 @@ namespace Core::LinAlg::Matrix<3, 3> iFin_result(Core::LinAlg::Initialization::zero); FOUR_C_EXPECT_THROW_WITH_MESSAGE( material->evaluate_inverse_inelastic_def_grad(&FM_, iFin_other, iFin_result), - Core::Exception, "Local Newton Loop did not converge"); + Core::Exception, + "Error in InelasticDefgradTransvIsotropElastViscoplast: Local Newton Loop did not converge " + "for the given loop settings!"); } TEST_F(InelasticDefgradFactorsTest, TestLocalNewtonDivergenceHandlingContinue) @@ -2050,7 +2015,9 @@ namespace Core::LinAlg::Matrix<3, 3> iFin_result(Core::LinAlg::Initialization::zero); FOUR_C_EXPECT_THROW_WITH_MESSAGE( material->evaluate_inverse_inelastic_def_grad(&FM_, iFin_other, iFin_result), - Core::Exception, "Local Newton Loop did not converge"); + Core::Exception, + "Error in InelasticDefgradTransvIsotropElastViscoplast: Local Newton Loop did not converge " + "for the given loop settings!"); } TEST_F(InelasticDefgradFactorsTest, TestLocalNewtonResidualConvergence) @@ -2127,7 +2094,9 @@ namespace Core::LinAlg::Matrix<3, 3> iFin_result(Core::LinAlg::Initialization::zero); FOUR_C_EXPECT_THROW_WITH_MESSAGE( material->evaluate_inverse_inelastic_def_grad(&FM_, iFin_other, iFin_result), - Core::Exception, "Local Newton Loop did not converge"); + Core::Exception, + "Error in InelasticDefgradTransvIsotropElastViscoplast: Local Newton Loop did not converge " + "for the given loop settings!"); } TEST_F(InelasticDefgradFactorsTest, TestLocalNewtonIncrementRatioConvergence) @@ -2215,7 +2184,9 @@ namespace Core::LinAlg::Matrix<3, 3> iFin_result(Core::LinAlg::Initialization::zero); FOUR_C_EXPECT_THROW_WITH_MESSAGE( material->evaluate_inverse_inelastic_def_grad(&FM_, iFin_other, iFin_result), - Core::Exception, "Local Newton Loop did not converge"); + Core::Exception, + "Error in InelasticDefgradTransvIsotropElastViscoplast: Local Newton Loop did not converge " + "for the given loop settings!"); } TEST_F(InelasticDefgradFactorsTest, TestLocalNewtonResidualAndIncrementRatioConvergence) @@ -2322,15 +2293,16 @@ namespace // the one-step formulation fails to converge FOUR_C_EXPECT_THROW_WITH_MESSAGE( material_one_step->evaluate_inverse_inelastic_def_grad(&FM, iFin_other, iFin_result), - Core::Exception, "Local Newton evaluation has failed with err status overflow_error"); + Core::Exception, + "Local Newton evaluation has failed and there is no evaluation management strategy"); // the local substepping formulation converges material_substepping->evaluate_inverse_inelastic_def_grad(&FM, iFin_other, iFin_result); Core::LinAlg::Matrix<3, 3> iFin_result_ref{Core::LinAlg::Initialization::zero}; - iFin_result_ref(0, 0) = 0.71055164642; - iFin_result_ref(1, 1) = 1.18632088172; - iFin_result_ref(2, 2) = 1.18632088172; + iFin_result_ref(0, 0) = 0.71055158583; + iFin_result_ref(1, 1) = 1.18632093229; + iFin_result_ref(2, 2) = 1.18632093229; FOUR_C_EXPECT_NEAR(iFin_result, iFin_result_ref, 1.0e-10); } diff --git a/unittests/mat/4C_multiplicative_split_defgrad_elasthyper_service_test.cpp b/unittests/mat/4C_multiplicative_split_defgrad_elasthyper_service_test.cpp index 95a5833cbd1..5f2094eb9e2 100644 --- a/unittests/mat/4C_multiplicative_split_defgrad_elasthyper_service_test.cpp +++ b/unittests/mat/4C_multiplicative_split_defgrad_elasthyper_service_test.cpp @@ -8,7 +8,7 @@ #include #include "4C_linalg_fixedsizematrix.hpp" -#include "4C_linalg_fixedsizematrix_voigt_notation.hpp" +#include "4C_linalg_symmetric_tensor.hpp" #include "4C_mat_elast_coupneohooke.hpp" #include "4C_mat_elast_isoneohooke.hpp" #include "4C_mat_elasthyper_service.hpp" @@ -175,58 +175,32 @@ namespace iFinM(2, 1) = 0.0000000000000000; iFinM(2, 2) = 0.8021447823814358; //************************************************** - Core::LinAlg::Matrix<3, 3> CTM_ref_{Core::LinAlg::Initialization::zero}; - CTM_ref_(0, 0) = 21.0000000000000000; - CTM_ref_(0, 1) = 0.0000000000000000; - CTM_ref_(0, 2) = 0.0000000000000000; - CTM_ref_(1, 0) = 0.0000000000000000; - CTM_ref_(1, 1) = 21.0000000000000000; - CTM_ref_(1, 2) = 0.0000000000000000; - CTM_ref_(2, 0) = 0.0000000000000000; - CTM_ref_(2, 1) = 0.0000000000000000; - CTM_ref_(2, 2) = 21.0000000000000000; + Core::LinAlg::SymmetricTensor thermal_contribution_to_2pk_stress_ref_{}; + thermal_contribution_to_2pk_stress_ref_(0, 0) = 60.3191058810404357; + thermal_contribution_to_2pk_stress_ref_(0, 1) = 32.4795185513294626; + thermal_contribution_to_2pk_stress_ref_(0, 2) = 0.0000000000000000; + thermal_contribution_to_2pk_stress_ref_(1, 0) = 32.4795185513294626; + thermal_contribution_to_2pk_stress_ref_(1, 1) = 103.2384696810115088; + thermal_contribution_to_2pk_stress_ref_(1, 2) = 0.0000000000000000; + thermal_contribution_to_2pk_stress_ref_(2, 0) = 0.0000000000000000; + thermal_contribution_to_2pk_stress_ref_(2, 1) = 0.0000000000000000; + thermal_contribution_to_2pk_stress_ref_(2, 2) = 37.1194497729479664; //************************************************** - Core::LinAlg::Matrix<3, 3> dCTM_dT_ref_{Core::LinAlg::Initialization::zero}; - dCTM_dT_ref_(0, 0) = 0.2000000000000000; - dCTM_dT_ref_(0, 1) = 0.0000000000000000; - dCTM_dT_ref_(0, 2) = 0.0000000000000000; - dCTM_dT_ref_(1, 0) = 0.0000000000000000; - dCTM_dT_ref_(1, 1) = 0.2000000000000000; - dCTM_dT_ref_(1, 2) = 0.0000000000000000; - dCTM_dT_ref_(2, 0) = 0.0000000000000000; - dCTM_dT_ref_(2, 1) = 0.0000000000000000; - dCTM_dT_ref_(2, 2) = 0.2000000000000000; - //************************************************** - Core::LinAlg::Matrix<3, 3> S_ref{Core::LinAlg::Initialization::zero}; - S_ref(0, 0) = -60.3191058810404357; - S_ref(0, 1) = -32.4795185513294626; - S_ref(0, 2) = 0.0000000000000000; - S_ref(1, 0) = -32.4795185513294626; - S_ref(1, 1) = -103.2384696810115088; - S_ref(1, 2) = 0.0000000000000000; - S_ref(2, 0) = 0.0000000000000000; - S_ref(2, 1) = 0.0000000000000000; - S_ref(2, 2) = -37.1194497729479664; - //************************************************** - Core::LinAlg::Matrix<3, 3> pS_pT_ref_{Core::LinAlg::Initialization::zero}; - pS_pT_ref_(0, 0) = -0.0000941798851085; - pS_pT_ref_(0, 1) = -0.0000507122458277; - pS_pT_ref_(0, 2) = -0.0000000000000000; - pS_pT_ref_(1, 0) = -0.0000507122458277; - pS_pT_ref_(1, 1) = -0.0001611924956665; - pS_pT_ref_(1, 2) = -0.0000000000000000; - pS_pT_ref_(2, 0) = -0.0000000000000000; - pS_pT_ref_(2, 1) = -0.0000000000000000; - pS_pT_ref_(2, 2) = -0.0000579568523745; + Core::LinAlg::SymmetricTensor + p_thermal_contribution_to_2pk_stress_p_temperature_ref_{}; + p_thermal_contribution_to_2pk_stress_p_temperature_ref_(0, 0) = 0.0000941798851085; + p_thermal_contribution_to_2pk_stress_p_temperature_ref_(0, 1) = 0.0000507122458277; + p_thermal_contribution_to_2pk_stress_p_temperature_ref_(0, 2) = 0.0000000000000000; + p_thermal_contribution_to_2pk_stress_p_temperature_ref_(1, 0) = 0.0000507122458277; + p_thermal_contribution_to_2pk_stress_p_temperature_ref_(1, 1) = 0.0001611924956665; + p_thermal_contribution_to_2pk_stress_p_temperature_ref_(1, 2) = 0.0000000000000000; + p_thermal_contribution_to_2pk_stress_p_temperature_ref_(2, 0) = 0.0000000000000000; + p_thermal_contribution_to_2pk_stress_p_temperature_ref_(2, 1) = 0.0000000000000000; + p_thermal_contribution_to_2pk_stress_p_temperature_ref_(2, 2) = 0.0000579568523745; // set thermal info const double thermal_expansion_fac = 0.1; - Core::LinAlg::Matrix<3, 3> iCinM{Core::LinAlg::Initialization::zero}; - iCinM.multiply_nt(1.0, iFinM, iFinM, 0.0); - Core::LinAlg::Matrix<6, 1> iCinV{Core::LinAlg::Initialization::zero}; - Core::LinAlg::Voigt::Stresses::matrix_to_vector(iCinM, iCinV); - // Create summand vector std::vector> potsum; Core::IO::InputParameterContainer elast_pot_coup_neo_hooke_data; @@ -238,37 +212,15 @@ namespace dynamic_cast(coup_neo_hooke_params.get()))); - // evaluate thermal quantities - Mat::ThermalQuantities thermal_quantities = Mat::evaluate_thermal_quantities( - delta_temperature, thermal_expansion_fac, iFinM, 0, 0, potsum); - - // evaluate thermal stress factors - Mat::StressFactors thermal_stress_factors; - Mat::calculate_gamma_delta(thermal_stress_factors.gamma, thermal_stress_factors.delta, - thermal_quantities.prinv, thermal_quantities.dPI, thermal_quantities.ddPII); - - // evaluate thermal contribution to second Piola-Kirchhoff stress - Core::LinAlg::Matrix<6, 1> S_V{Core::LinAlg::Initialization::zero}; - Mat::add_thermal_stress_contribution( - S_V, thermal_quantities, thermal_stress_factors, iCinV, 1.0 / iFinM.determinant()); - Core::LinAlg::Matrix<3, 3> S_M{Core::LinAlg::Initialization::zero}; - Core::LinAlg::Voigt::Stresses::vector_to_matrix(S_V, S_M); - // evaluate partial derivative of 2nd Piola-Kirchhoff stress wrt temperature - Core::LinAlg::Matrix<6, 1> pS_pT_V = - Mat::compute_partial_d_stress_d_temperature(iFinM, thermal_quantities); - Core::LinAlg::Matrix<3, 3> pS_pT_M{Core::LinAlg::Initialization::zero}; - Core::LinAlg::Voigt::Stresses::vector_to_matrix(pS_pT_V, pS_pT_M); - - - // postprocessed data for assertions - Core::LinAlg::Matrix<3, 3> CTM{Core::LinAlg::Initialization::zero}; - Core::LinAlg::Voigt::Stresses::vector_to_matrix(thermal_quantities.CTV, CTM); - Core::LinAlg::Matrix<3, 3> dCTM_dT{Core::LinAlg::Initialization::zero}; - Core::LinAlg::Voigt::Strains::vector_to_matrix(thermal_quantities.dCTdTV, dCTM_dT); + auto thermoelastic_stress_contribution = + Mat::ThermalExpansion::compute_thermoelastic_stress_contribution( + delta_temperature, thermal_expansion_fac, potsum, 0, 0); - FOUR_C_EXPECT_NEAR(CTM, CTM_ref_, 1.0e-10); - FOUR_C_EXPECT_NEAR(dCTM_dT, dCTM_dT_ref_, 1.0e-10); - FOUR_C_EXPECT_NEAR(S_M, S_ref, 1.0e-10); - FOUR_C_EXPECT_NEAR(pS_pT_M, pS_pT_ref_, 1.0e-10); + const auto pk2_stress_contribution = Mat::ThermalExpansion::compute_pk2_stress_contribution( + thermoelastic_stress_contribution, iFinM); + FOUR_C_EXPECT_NEAR( + pk2_stress_contribution.value, thermal_contribution_to_2pk_stress_ref_, 1.0e-10); + FOUR_C_EXPECT_NEAR(pk2_stress_contribution.temperature_derivative, + p_thermal_contribution_to_2pk_stress_p_temperature_ref_, 1.0e-10); } } // namespace diff --git a/unittests/mat/4C_multiplicative_split_defgrad_elasthyper_test.cpp b/unittests/mat/4C_multiplicative_split_defgrad_elasthyper_test.cpp index 3840c0be331..d49a344a3df 100644 --- a/unittests/mat/4C_multiplicative_split_defgrad_elasthyper_test.cpp +++ b/unittests/mat/4C_multiplicative_split_defgrad_elasthyper_test.cpp @@ -9,9 +9,11 @@ #include "4C_global_data.hpp" #include "4C_linalg_fixedsizematrix.hpp" +#include "4C_linalg_symmetric_tensor.hpp" #include "4C_mat_elasthyper_service.hpp" #include "4C_mat_material_factory.hpp" #include "4C_mat_multiplicative_split_defgrad_elasthyper.hpp" +#include "4C_mat_multiplicative_split_defgrad_elasthyper_service.hpp" #include "4C_mat_par_bundle.hpp" #include "4C_material_parameter_base.hpp" #include "4C_ssi_input.hpp" @@ -121,6 +123,8 @@ namespace std::vector inelastic_defgrad_factor_ids = {inelastic_defgrad_id}; multiplicativeSplitDefgradData.add("INELDEFGRADFACIDS", inelastic_defgrad_factor_ids); multiplicativeSplitDefgradData.add("DENS", 1.32e1); + multiplicativeSplitDefgradData.add("REF_TEMPERATURE", 293.0); + multiplicativeSplitDefgradData.add("THERMAL_EXPANSION_COEFFICIENT", 0.1); // get pointer to parameter class parameters_multiplicative_split_defgrad_ = @@ -547,8 +551,9 @@ namespace stress_fact.gamma = gamma_ref_; stress_fact.delta = delta_ref_; + const Core::LinAlg::SymmetricTensor ST{}; // no stress due to thermal expansion Core::LinAlg::Matrix<6, 9> dSdiFin = - multiplicative_split_defgrad_->evaluated_sdi_fin(kinemat_quant, stress_fact); + multiplicative_split_defgrad_->evaluate_d_stress_d_ifin(kinemat_quant, stress_fact, ST); FOUR_C_EXPECT_NEAR(dSdiFin, dSdiFin_ref_, 1.0e-10); } @@ -624,7 +629,7 @@ namespace // do the actual call that is tested auto source(Mat::PAR::InelasticSource::concentration); - Core::LinAlg::Matrix<6, 1> dSdx(Core::LinAlg::Initialization::zero); + // reference solution Core::LinAlg::Matrix<6, 1> dSdx_ref; dSdx_ref(0) = -1.907155639254611e-05; @@ -634,7 +639,8 @@ namespace dSdx_ref(4) = 1.08343997650926e-06; dSdx_ref(5) = 1.949130554546719e-06; - multiplicative_split_defgrad_->evaluate_od_stiff_mat(source, &FM_, dSdiFin_ref_, dSdx); + Core::LinAlg::Matrix<6, 1> dSdx = + multiplicative_split_defgrad_->evaluate_od_stiff_mat(source, &FM_, dSdiFin_ref_); FOUR_C_EXPECT_NEAR(dSdx, dSdx_ref, 1.0e-10); } diff --git a/unittests/mat/vplast/4C_vplast_reform_johnsoncook_test.cpp b/unittests/mat/vplast/4C_vplast_reform_johnsoncook_test.cpp index bd59145407f..1c43791bc1c 100644 --- a/unittests/mat/vplast/4C_vplast_reform_johnsoncook_test.cpp +++ b/unittests/mat/vplast/4C_vplast_reform_johnsoncook_test.cpp @@ -23,6 +23,58 @@ namespace { using namespace FourC; + struct ReformulatedJohnsonCookLaw + { + //! parameters + std::shared_ptr params; + + //! material + std::shared_ptr material; + }; + + int make_unique_viscoplastic_law_id() + { + static int viscoplastic_law_id = 1; + return viscoplastic_law_id; + } + + + ReformulatedJohnsonCookLaw set_up_reformulated_johnson_cook_law( + const Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorRegistrationSettings + error_registration_settings) + { + const int viscoplastic_law_id = make_unique_viscoplastic_law_id(); + + Core::IO::InputParameterContainer vplast_law_reformulated_JC_data; + vplast_law_reformulated_JC_data.add("STRAIN_RATE_PREFAC", 1.0); + vplast_law_reformulated_JC_data.add("STRAIN_RATE_EXP_FAC", 0.014); + vplast_law_reformulated_JC_data.add("INIT_YIELD_STRENGTH", 792.0); + vplast_law_reformulated_JC_data.add("ISOTROP_HARDEN_PREFAC", 510.0); + vplast_law_reformulated_JC_data.add("ISOTROP_HARDEN_EXP", 0.26); + vplast_law_reformulated_JC_data.add("REF_TEMPERATURE", 293.0); + vplast_law_reformulated_JC_data.add("MELT_TEMPERATURE", 1793.0); + vplast_law_reformulated_JC_data.add("TEMPERATURE_SENS", 1.03); + auto params = std::dynamic_pointer_cast( + std::shared_ptr(Mat::make_parameter(viscoplastic_law_id, + Core::Materials::MaterialType::mvl_reformulated_Johnson_Cook, + vplast_law_reformulated_JC_data))); + + auto material = std::make_shared( + params.get(), error_registration_settings); + + // call setup method for ReformulatedJohnsonCook + int numgp = 1; + material->setup(numgp, {}, {}); + // pre_evaluate + Teuchos::ParameterList param_list{}; + param_list.set("temperature", 313.0); + material->pre_evaluate(param_list, 0); + + return {.params = params, .material = material}; + } + + + class ReformJohnsonCookTest : public ::testing::Test { protected: @@ -33,34 +85,14 @@ namespace equiv_plastic_strain_ = 0.001; // manually create viscoplastic law (ReformulatedJohnsonCook) - Core::IO::InputParameterContainer vplast_law_reformulated_JC_data; - vplast_law_reformulated_JC_data.add("STRAIN_RATE_PREFAC", 1.0); - vplast_law_reformulated_JC_data.add("STRAIN_RATE_EXP_FAC", 0.014); - vplast_law_reformulated_JC_data.add("INIT_YIELD_STRENGTH", 792.0); - vplast_law_reformulated_JC_data.add("ISOTROP_HARDEN_PREFAC", 510.0); - vplast_law_reformulated_JC_data.add("ISOTROP_HARDEN_EXP", 0.26); - vplast_law_reformulated_JC_data.add("REF_TEMPERATURE", 293.0); - vplast_law_reformulated_JC_data.add("MELT_TEMPERATURE", 1793.0); - vplast_law_reformulated_JC_data.add("TEMPERATURE_SENS", 1.03); - params_vplast_law_reformulated_JC_ = - std::dynamic_pointer_cast( - std::shared_ptr(Mat::make_parameter(1, - Core::Materials::MaterialType::mvl_reformulated_Johnson_Cook, - vplast_law_reformulated_JC_data))); - vplast_law_reformulated_JC_ = std::make_shared( - params_vplast_law_reformulated_JC_.get()); - - // call setup method for ReformulatedJohnsonCook - int numgp = 8; // HEX8 element, although not really relevant for the tested methods - vplast_law_reformulated_JC_->setup(numgp, {}, {}); - - // parameter list - Teuchos::ParameterList param_list{}; - param_list.set("temperature", 313.0); - - - // call pre_evaluate - vplast_law_reformulated_JC_->pre_evaluate(param_list, 0); + const double max_plastic_strain_incr_and_deriv_incr = std::exp(30.0); + const auto reformulated_johnson_cook_law = + set_up_reformulated_johnson_cook_law({.register_plastic_strain_incr_overflow = true, + .max_plastic_strain_incr = max_plastic_strain_incr_and_deriv_incr, + .register_plastic_strain_deriv_incr_overflow = true, + .max_plastic_strain_deriv_incr = max_plastic_strain_incr_and_deriv_incr}); + params_vplast_law_reformulated_JC_ = reformulated_johnson_cook_law.params; + vplast_law_reformulated_JC_ = reformulated_johnson_cook_law.material; } // equivalent stress @@ -110,15 +142,39 @@ namespace // compute solution from the viscoplasticity law double plastic_strain_rate_reformulated_JC = vplast_law_reformulated_JC_->evaluate_plastic_strain_rate( - equiv_stress_, equiv_plastic_strain_, 1.0, std::exp(30.0), err_status, false); + equiv_stress_, equiv_plastic_strain_, 1.0, err_status, false); if (err_status != Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType::no_errors) FOUR_C_THROW("Error encountered during testing of TestEvaluatePlasticStrainRate"); - - - // compare solutions EXPECT_NEAR( plastic_strain_rate_reformulated_JC_solution_, plastic_strain_rate_reformulated_JC, 1.0e-8); + + // test registering of the overflow error + const auto ref_jc_register_both_with_zero_incr = + set_up_reformulated_johnson_cook_law({.register_plastic_strain_incr_overflow = true, + .max_plastic_strain_incr = + 1.0e-16, // effectively 0-tolerance for plastic strain increments -> results in + // overflow error regardless of the computed plastic strain increment + // value + .register_plastic_strain_deriv_incr_overflow = true, + .max_plastic_strain_deriv_incr = 1.0e-16}); + plastic_strain_rate_reformulated_JC = + ref_jc_register_both_with_zero_incr.material->evaluate_plastic_strain_rate( + equiv_stress_, equiv_plastic_strain_, 1.0, err_status, false); + EXPECT_EQ(err_status, + Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType::overflow_error); + + const auto ref_jc_register_none_with_zero_incr = + set_up_reformulated_johnson_cook_law({.register_plastic_strain_incr_overflow = false, + .max_plastic_strain_incr = + 1.0e-16, // same test as above, but now without registering the error + .register_plastic_strain_deriv_incr_overflow = false, + .max_plastic_strain_deriv_incr = 1.0e-16}); + plastic_strain_rate_reformulated_JC = + ref_jc_register_none_with_zero_incr.material->evaluate_plastic_strain_rate( + equiv_stress_, equiv_plastic_strain_, 1.0, err_status, false); + EXPECT_EQ( + err_status, Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType::no_errors); } TEST_F(ReformJohnsonCookTest, TestEvaluatePlasticStrainRateDerivatives) @@ -135,10 +191,17 @@ namespace Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType::no_errors; // compute solution from the viscoplasticity law + const double max_plastic_strain_incr_and_deriv_incr = std::exp(30.0); + const auto ref_jc_register_both_with_set_incr = + set_up_reformulated_johnson_cook_law({.register_plastic_strain_incr_overflow = true, + .max_plastic_strain_incr = max_plastic_strain_incr_and_deriv_incr, + .register_plastic_strain_deriv_incr_overflow = true, + .max_plastic_strain_deriv_incr = max_plastic_strain_incr_and_deriv_incr}); Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::PlasticStrainRateDerivs deriv_plastic_strain_rate_reformulated_JC = - vplast_law_reformulated_JC_->evaluate_derivatives_of_plastic_strain_rate( - equiv_stress_, equiv_plastic_strain_, 1.0, std::exp(30.0), err_status, false); + ref_jc_register_both_with_set_incr.material + ->evaluate_derivatives_of_plastic_strain_rate( + equiv_stress_, equiv_plastic_strain_, 1.0, err_status, false); if (err_status != Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType::no_errors) FOUR_C_THROW("Error encountered during testing of TestEvaluatePlasticStrainRateDerivatives"); @@ -150,6 +213,36 @@ namespace deriv_plastic_strain_rate_reformulated_JC.deriv_plastic_strain, 1.0e-6); EXPECT_NEAR(deriv_plastic_strain_rate_reformulated_JC_solution_.deriv_temperature, deriv_plastic_strain_rate_reformulated_JC.deriv_temperature, 1.0e-6); + + + + const auto ref_jc_register_both_with_zero_incr = + set_up_reformulated_johnson_cook_law({.register_plastic_strain_incr_overflow = true, + .max_plastic_strain_incr = + 1.0e-16, // effectively 0-tolerance for plastic strain increments -> results + // in overflow error regardless of the computed plastic strain + // increment value + .register_plastic_strain_deriv_incr_overflow = true, + .max_plastic_strain_deriv_incr = 1.0e-16}); + deriv_plastic_strain_rate_reformulated_JC = + ref_jc_register_both_with_zero_incr.material->evaluate_derivatives_of_plastic_strain_rate( + equiv_stress_, equiv_plastic_strain_, 1.0, err_status, false); + + EXPECT_EQ(err_status, Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType:: + failed_computation_flow_resistance_derivs); + + + const auto ref_jc_register_none_with_zero_incr = + set_up_reformulated_johnson_cook_law({.register_plastic_strain_incr_overflow = false, + .max_plastic_strain_incr = + 1.0e-16, // same test as above, but now without registering the error + .register_plastic_strain_deriv_incr_overflow = false, + .max_plastic_strain_deriv_incr = 1.0e-16}); + deriv_plastic_strain_rate_reformulated_JC = + ref_jc_register_none_with_zero_incr.material->evaluate_derivatives_of_plastic_strain_rate( + equiv_stress_, equiv_plastic_strain_, 1.0, err_status, false); + EXPECT_EQ( + err_status, Mat::InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType::no_errors); } } // namespace