Further cleanup in preparation for the Adaptive Estimate Interpolation algorithm#2082
Further cleanup in preparation for the Adaptive Estimate Interpolation algorithm#2082dragos-ana wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR continues refactoring/cleanup of the finite-deformation viscoplastic constitutive update in preparation for Adaptive Estimate Interpolation (AEI), including clearer terminology (“constitutive update”), more consistent deformation-tensor handling, and more configurable error registration and Local Newton bookkeeping.
Changes:
- Introduces
ErrorRegistrationSettingsand updates viscoplastic law interfaces/call sites to use configurable overflow registration (incl. updated unit tests). - Refactors the local integration workflow to use a dedicated
LocalIntegrationDeformationTensorsstruct and enhances Local Newton bookkeeping/management. - Adds a dedicated unit test file for inelastic defgrad factor service utilities and updates regression expected results.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| unittests/mat/vplast/4C_vplast_reform_johnsoncook_test.cpp | Updates tests for new error-registration-settings API and overflow-registration behavior. |
| unittests/mat/4C_inelastic_defgrad_factors_test.cpp | Adjusts material test setup to include error registration settings; updates expected error messages/results. |
| unittests/mat/4C_inelastic_defgrad_factors_service_test.cpp | Adds new unit tests for deformation-tensor struct and Local Newton manager service behavior. |
| tests/input_files/mat_iso_viscoplast_refJC_log_timint_substepping.4C.yaml | Updates regression reference values due to constitutive-update/substepping changes. |
| src/mat/vplast/4C_mat_vplast_reform_johnsoncook.hpp | Updates viscoplastic law interface (uses_yield_surface, new error settings, gp-based update hooks). |
| src/mat/vplast/4C_mat_vplast_reform_johnsoncook.cpp | Implements error-registration-settings driven overflow checks in plastic strain rate (+ derivatives). |
| src/mat/vplast/4C_mat_vplast_law.hpp | Extends base law API (uses_yield_surface, gp-based update/update_gp_state) and updates signatures. |
| src/mat/4C_mat_inelastic_defgrad_factors.hpp | Renames “return mapping” to “constitutive update”; introduces error-free evaluation guard + new init estimate entry point. |
| src/mat/4C_mat_inelastic_defgrad_factors.cpp | Major refactor: tensor struct usage, per-GP update logic, error messaging, substepping interpolation changes, packing of plastic-flow flags. |
| src/mat/4C_mat_inelastic_defgrad_factors_service.hpp | Adds ErrorRegistrationSettings, expands LocalNewtonManager responsibilities, adds deformation-tensor helper struct. |
| src/mat/4C_mat_inelastic_defgrad_factors_service.cpp | Implements new LocalNewtonManager methods and per-GP TimeStepQuantities::update. |
| src/global_legacy_module/4C_global_legacy_module_validmaterials.cpp | Moves overflow-related settings under a dedicated input group and updates material input spec docs. |
561c255 to
8f45c0d
Compare
59c8a51 to
fe04870
Compare
for the Adaptive Estimate Interpolation: - The term 'constitutive update' is now used instead of 'return mapping' to avoid confusion, since our constitutive update also comprises the elastic predictor verification. Several frameworks in literature use 'return mapping' to comprise both stages, but we want to make this clear here. - Added struct for tracking all deformation tensors used for the local integration routines. These are then used consistently throughout the constitutive update routines. - Improved error handling by adding error registration settings, and only outputting detailed errors. Plastic strain rate derivative checks are now disabled by default, which has some implications for the substepping test -> changed results. Also, functions are guarded to only be evaluated if there are no evaluation errors currently. - Added tracking of plastic flow at each Gauss point to improve plasticity checks, such as the ones in the linearization and the update procedures. The update procedures are run separately per Gauss point. - Also added characteristic for viscoplastic laws: do they use yield surface or not? Important for the AEI subsequently. - Incorporated further logic from the viscoplastic inelastic factor to the dedicated Local Newton manager, such as solution and convergence quantities tracking and checking. - Added a dedicated unit tests file for the service of inelastic deformation gradient factors. - In preparation for the AEI: a method dedicated to determining the Local Newton estimate was used. This method will serve as the entry point for the AEI, along with manage_evaluation, which will be responsible for re-estimation. - Substepping: now the deformation gradient is interpolated, instead of the right CG tensor. This is also done in preparation for the AEI, to enable combining it with substepping.
fe04870 to
d2bfba3
Compare
lauraengelhardt
left a comment
There was a problem hiding this comment.
Thanks for cleaning up the formatting first 👍 That already removed a large part of the diff. I have one short question considering the test results.
I haven’t had time to fully review the rest of the PR yet, since all changes are contained in a single large commit (and also its late 😉). IMO, it would be very helpful to split changes into smaller commits - for example one for the error handling improvements, one for adding the unit tests, and one for the AEI preparation. This would make reviewing much easier 🙂 No need to do it here, but maybe something to keep in mind for the next PRs.
| NODE: 8 | ||
| QUANTITY: "stress_zz" | ||
| VALUE: 9.30776106016615358e+02 | ||
| VALUE: 9.31099439481397212e+02 |
There was a problem hiding this comment.
Just for my understanding: Can I ask what is the reason for the change of these values. I wouldn't expect the result to change that much just from a pure cleanup.
There was a problem hiding this comment.
We trigger local substepping if overflow is identified based on the plastic strain increments and the increments of their derivatives. Previously, we registered overflow for both plastic strain increments and derivative increments; however, I have seen in previous weeks that this strategy can overly constrain the local time integration. I have therefore adapted the formulation to only check overflow based on the plastic strain increments by default, and not also based on the derivative increments. This means that the overflow checking mechanism has changed, which leads to differences in the triggered substepping. Hence the observed differences in the test results.
The changes are substantial, I agree. But this is a weakness of the substepping formulation, which is very fragile and inconsistent anyway in my opinion, and should be removed or deprecated in some way in upcoming PRs on this material.
There was a problem hiding this comment.
The result changes make sense to me and are also changes in the "right" direction, compared to the non-substepping test
rjoussen
left a comment
There was a problem hiding this comment.
Exciting to see that we're moving towards AEI! If that helps you with merging the next step, I would also be fine with removing substepping first, and then add AEI on a cleaner state.
I left some comments and also have a more general question regarding overflow errors:
What exactly is the idea behind the "manual" overflow checking in the first place? In my simulations, I often end up setting these values super high so the simulation doesn't over-cautiously stop. As far as I know/remember, resulting nan-values are caught later on anyway. Or I guess formulated differently: Why are we setting a limit on these values when we could also just abort/trigger substepping/estimate adaptation when overflow actually happens?
| NODE: 8 | ||
| QUANTITY: "stress_zz" | ||
| VALUE: 9.30776106016615358e+02 | ||
| VALUE: 9.31099439481397212e+02 |
There was a problem hiding this comment.
The result changes make sense to me and are also changes in the "right" direction, compared to the non-substepping test
|
|
||
| /// 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; |
There was a problem hiding this comment.
I guess I'll need to see how this is actually used. Currently, I don't fully understand why viscoplastic laws without a strict yield surface require a different approach in the parent material. I would rather think the important distinction is whether or not viscoplastic laws manage their own history variables.
| * @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 | ||
| * (substepping procedure) | ||
| * | ||
| * @param[in] gp Gauss point | ||
| */ | ||
| virtual void update_gp_state(int gp) = 0; | ||
| virtual void update_gp_state(const unsigned int gp) = 0; |
There was a problem hiding this comment.
This was of course here before, but these methods should either be unified if possible or have more expressive names. But its hard to assess without any code in these functions.
| {.description = "Parameters used in the Local Newton--Raphson procedure " | ||
| "(viscoplastic corrector stage)", | ||
| .required = false}), | ||
| group("ERROR_REGISTRATION_SETTINGS", |
There was a problem hiding this comment.
| group("ERROR_REGISTRATION_SETTINGS", | |
| group<ErrorRegistrationSettings>("ERROR_REGISTRATION_SETTINGS", |
I think you can do something like this here and then use the .store function to get the constructed struct directly
| if (error_registration_settings.register_plastic_strain_incr_overflow) | ||
| { | ||
| FOUR_C_ASSERT_ALWAYS(error_registration_settings.max_plastic_strain_incr > 0.0, | ||
| "Maximum plastic strain increment must be > 0: current value = {}", | ||
| error_registration_settings.max_plastic_strain_incr); | ||
| } |
There was a problem hiding this comment.
This is coming directly from the input, where it is validated already. So I dont think another assert is needed here.
| void manage_evaluation( | ||
| const InelasticDefgradTransvIsotropElastViscoplastUtils::ErrorType& err_status, | ||
| InelasticDefgradTransvIsotropElastViscoplastUtils::EvaluationAction& eval_action) const; | ||
| InelasticDefgradTransvIsotropElastViscoplastUtils::EvaluationAction& eval_action); | ||
|
|
There was a problem hiding this comment.
I think this methods can stay const for now.
| // called in the redundant evaluate call, which is already handled -> direct return | ||
| // without calling this function) | ||
| prepare_return_mapping(); | ||
| prepare_constitutive_update(); |
There was a problem hiding this comment.
Will prepare_constitutive_update() do more in the future? Currently it is so small that I would be in favor of just doing the necessary things here explicitly. This way, its less hidden. On top of that, prepare* sound like something that needs to be done before the actual function call, which is not the case here.
| 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 |
There was a problem hiding this comment.
| // update inverse inelastic defgrad and plastic strain | |
| // update inverse inelastic defgrad and plastic strain | |
| is_plastic_gp_[gp_] = false; |
| 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!")); | ||
| } | ||
| } |
There was a problem hiding this comment.
this only makes sense if determine_local_newton_init_estimate will be able to set an error status.
| // reset Local Newton iteration count | ||
| local_newton_manager_.set_iteration_count(0); | ||
| // initialize local Newton | ||
| local_newton_manager_.reset_iter(); |
There was a problem hiding this comment.
Would it be possible to construct a local (in a programming sense) local_newton_manager in every local newton loop? This would probably prevent a lot of resetting everywhere. The only thing that would need to change is that the number of iterations are - in the end - only, written to a class variable per gp, such that they can be plotted.
errors. Plastic strain rate derivative checks are now disabled by default, since the detecting overflow here is not straightforward and can overconstrain the computation.
This has some implications for the substepping test -> changed results.
the linearization and the update procedures.