Refactor the drucker prager model to use tensors instead of matrices#2007
Refactor the drucker prager model to use tensors instead of matrices#2007ischeider wants to merge 1 commit into4C-multiphysics:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Refactors the structural Plastic Drucker–Prager material implementation to operate directly on Core::LinAlg tensor types (symmetric 2nd/4th order tensors) rather than Voigt matrices, aligning it with the codebase’s ongoing tensor-based constitutive model direction.
Changes:
- Reworked
PlasticDruckerPrager::evaluate()to use tensor operations end-to-end (stress, deviatoric split, J2, updates). - Updated history storage/serialization from Voigt vectors to
SymmetricTensor<double,3,3>. - Reimplemented consistent tangent assembly for cone/apex returns using tensor generators (
identity,symmetric_identity,dyadic,ddot).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
src/mat/4C_mat_plasticdruckerprager.hpp |
Updates public API signatures and internal history storage to tensor types; removes FAD-based interfaces. |
src/mat/4C_mat_plasticdruckerprager.cpp |
Implements tensor-based return mapping and tangent setup; updates pack/unpack and output extraction for tensor history. |
| if (Phi_trial / std::abs(cohesion) > params_->abstol_) | ||
| { |
There was a problem hiding this comment.
Phi_trial / std::abs(cohesion) will divide by zero when the input parameter C (cohesion) is 0.0, which is currently allowed by the material input spec. Consider using a cohesion-independent yield tolerance (e.g., compare Phi_trial against abstol_ * max(1, |cohesion|)), or explicitly validate/throw when cohesion == 0.0 if that case is unsupported.
| Dgamma = Core::Utils::solve_local_newton( | ||
| returnToConeFunctAndDeriv, Dgamma, params_->abstol_ * cohesion, itermax); | ||
| strainbar_p = strainbarpllast_.at(gp) + xi * Dgamma; |
There was a problem hiding this comment.
solve_local_newton(..., params_->abstol_ * cohesion, ...) can pass a zero or negative tolerance (if cohesion is 0 or negative), which breaks the Newton convergence criterion and can lead to non-termination until max-iterations/throw. Use a strictly positive tolerance (e.g., abstol_ * max(1, |cohesion|) or just abstol_) and/or validate cohesion > 0 up-front.
| strainbar_p = strainbarpllast_.at(gp) + xi * Dgamma; | ||
| devstress *= (1.0 - G * Dgamma / std::sqrt(J2)); | ||
| p = p_trial - kappa * etabar * Dgamma; |
There was a problem hiding this comment.
In the cone-return branch, devstress is rescaled by 1 - G*Dgamma/std::sqrt(J2). If the trial state is (nearly) hydrostatic then J2 == 0 and this will divide by zero before the code checks whether it should switch to the apex return. Consider detecting J2 near zero early and going directly to the apex return (or otherwise avoiding any 1/sqrt(J2) operations until J2 is known to be safely > 0).
| const double nd = std::sqrt(ddot(devstrain, devstrain)); | ||
| const auto D = devstrain / nd; | ||
|
|
There was a problem hiding this comment.
nd = std::sqrt(ddot(devstrain, devstrain)) can be zero for a purely volumetric (hydrostatic) strain state. The subsequent normalization D = devstrain / nd (and the 1/nd terms in epfac/epfac2) will then produce NaNs in the consistent tangent. Add a guard for nd near zero (e.g., treat as apex case, fall back to elastic tangent, or assert if cone return is not valid for nd==0).
2b993ef to
10b82d1
Compare
10b82d1 to
47c364d
Compare
Description and Context
Now also the Drucker Prager Material model is supposed to use tensors instead of matrices.
The changes are significant though (all the peculiar scalar types are gone, and the FAD routines vanished then as well).
GitHub Copilot assisted a lot ;-)
Interested parties
@BishrMaradni