Skip to content

Conversation

YiminJin
Copy link
Contributor

This PR is an implementation of plastic dilation in the framework of ASPECT. Currently, plastic dilation is added to the Drucker Prager rheology, but is only available in the ViscoPlastic material model. It solves the oscillation problem shown in #5953.

I have tested the Picard iteration method, the defect correction method (DCM) and Newton method with the strip-footing experiment, and they all gave the correct result:
amg_newton
The convergence rates of different nonlinear solvers are as expected: Newton > DCM > Picard (either with AMG or with GMG).

VEP model with dilation angle ($\psi$) identical to the friction angle ($\phi$) has two distinctive features:

  1. The shear bands develop along the Coulomb angle;
  2. The width of shear bands are independent on the grid size.

The features can be observed in the numerical results of Kaus' (2010) benchmark (without viscoplastic damper):
kaus_2010

The reason of feature 1 has been widely discussed and verified, while the reason of feature 2 is not so clear (the theory of associated/non-associated plastic flow can explain it, but I do not fully understand the theory).

I am sorry for modifying over 1000 lines of codes in a single PR. Please let me know if you find something confusing in my codes.

Copy link
Member

@tjhei tjhei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the reasoning for splitting dilation into LHS and RHS and the change to the -2/3 term for incompressible simulations, but the rest of the code looks clean and correct!
@naliboff can you take a look and then we can maybe discuss together?


// Only assemble this term if we are running incompressible, otherwise this term
// is already included on the LHS of the equation.
if (enable_prescribed_dilation && !material_model_is_compressible)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this no longer needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The boolean material_model_is_compressible determines whether the assembler StokesCompressibleStrainRateViscosityTerm is executed. I have forced the assembler to be executed when plastic dilation is enabled (see line 76 in source/simulator/assembly.cc and line 55 in source/simulator/newton.cc), so the volumetric part of strain rate is subtracted from the LHS, and this term is no longer needed.

Comment on lines +243 to 246
if (cell_data->is_compressible ||
cell_data->enable_prescribed_dilation)
for (unsigned int d=0; d<dim; ++d)
velocity_terms[d][d] -= viscosity_x_2 / 3. * div_u;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not see this change in the matrix-based version. Is this there as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the same change is made in the matrix-based assembler (line 76 in source/simulator/assembly.cc and line 55 in source/simulator/newton.cc).

this->get_newton_handler().parameters.newton_derivative_scaling_factor;

active_cell_data.enable_newton_derivatives = true;
active_cell_data.enable_newton_derivatives = (Parameters<dim>::is_defect_correction(this->get_parameters().nonlinear_solver)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With your change we now create the table for newtion_derivatives if dilation=true but we are not using a Newton solver. Is this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the Newton derivative tables are not created if the condition on the RHS of line 433 is not fulfilled. I have added if (active_cell_data.enable_newton_derivatives) before reinitializing those tables (line 461).

@tjhei
Copy link
Member

tjhei commented Jun 12, 2025

Finally, it would be good to have some simple tests that exercise the new code. In fact the tests are currently broken:

/__w/aspect/aspect/tests/prescribed_dilation.cc:211:40: error: 'class aspect::MaterialModel::PrescribedPlasticDilation<2>' has no member named 'dilation'

@naliboff
Copy link
Contributor

@YiminJin - Thank you for continuing to work on this and open the PR!

A few initial comments and thoughts from your initial post (more to come in the review):

  1. I agree the total width of the shear band looks very similar across grid refinement levels, but the strain rate within the shear band is certainly changing as seen in the Brick Benchmark case. As such, I think the quasi-length scale introduced by the plastic dilation is different than the one introduced by the plastic damper term (i.e., the strain rate should not change once the damper length scale is resolved).

  2. Following on point 1, does the strain-rate within the strip-footing experiment change at all as a function of resolution?

Copy link
Contributor

@naliboff naliboff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YiminJin - Nice work on this PR, it is in very good shape in terms of the structure, readability, and formatting. I confess I am having a very hard time evaluating the correctness of specific details, without seeing a higher-level summary of the equations and approach. Maybe we can discuss this in person? In any case, thank you again for pushing this forward and this looks like great progress!

@YiminJin
Copy link
Contributor Author

As such, I think the quasi-length scale introduced by the plastic dilation is different than the one introduced by the plastic damper term

I think I misunderstood the theory about associated/non-associated plastic flow. I reviewed the theory and it did not say that associated plastic flow is essentially mesh-independent. On the contrary, since we use a local method for plastic yielding (not global methods such as the strain gradient method), the thickness of the shear bands should be mesh-dependent. I will try to figure out why the shear bands behave like this in my results.

@YiminJin
Copy link
Contributor Author

Following on point 1, does the strain-rate within the strip-footing experiment change at all as a function of resolution?

The strain rate field of strip-footing experiment does not change with refinement level. Here is the comparison:
strip_footing

@bobmyhill
Copy link
Member

@YiminJin Nice work! I won't add another review, but I wanted to ask something. When you say "they all gave the correct result", do you mean the correct result, or just the same result? In #5953 you suggested that this was in fact the incorrect result (or at least different from your elASPECT code).

Whatever your answer, I don't think this should impact the merging of this PR. It would just be good to know what will still need fixing after this PR is merged (and why, if that's become clearer since last year).

@YiminJin
Copy link
Contributor Author

I have found a simple way to change the 2D models in ASPECT to plane-strain models. After the modification, the results now look like this:
strip_footing
kaus_2010

However, the Newton solver has some bugs currently, and the GMG version has not been implemented, so the new modifications are not pushed. Besides, my modifications conflict with some other PRs that use the orginal PrescribedPlasticDilation, so I think I had better put the "standard" plastic dilation terms to somewhere else.

@bobmyhill
Copy link
Member

bobmyhill commented Jun 14, 2025

@YiminJin thanks for your answer! It's brilliant to see that you have isolated the cause of the difference between elASPECT and ASPECT results.

Could you clarify the difference you have identified between "2D models in ASPECT" and "plane-strain models"? It is my understanding that 2D models in ASPECT are explicitly using the plane-strain approximation: https://aspect-documentation.readthedocs.io/en/latest/user/methods/basic-equations/2d-models.html

Would it be equivalent to say that one of the "plastic dilation" formulations implicitly assumes isotropic dilation? If so, it is interesting that the two approximations produce such different results, and we should discuss as a larger team what we want in our final implementation.

@YiminJin
Copy link
Contributor Author

Could you clarify the difference you have identified between "2D models in ASPECT" and "plane-strain models"? It is my understanding that 2D models in ASPECT are explicitly using the plane-strain approximation

There are two functions in ASPECT that are inconsistent with plane strain:

  1. Function deviator(), which is frequently used in material models. It is defined as $\text{dev}(A) := A - \text{trace}(A) / \text{dim}$, while in plane-strain assumption it should always be $\text{dev}(A) = A - \text{trace}(A) / 3$.
  2. Function second_invariant(), which is defined as $-A_{ij}A_{ij}/2$, but in plane strain case the contribution of $A_{33}$ should also be included.

After replacing the two functions by the plane strain version, the shear bands become sharp.

Would it be equivalent to say that one of the "plastic dilation" formulations implicitly assumes isotropic dilation?

I do not understand this question. Could you specify the "plastic dilation formulation" and the definition of "isotropic dilation" ? (Is there anisotropic dilation?)

we should discuss as a larger team what we want in our final implementation.

Sure! I hope we could make progress together.

@bobmyhill
Copy link
Member

There are two functions in ASPECT that are inconsistent with plane strain

Can you raise a GitHub Issue describing the problem? I agree with your assessment, but it would be good to ask the other developers (a) whether they see something we don't, and (b) how they think we should address the problem given that any change would be a breaking change.

Could you specify the "plastic dilation formulation" and the definition of "isotropic dilation" ? (Is there anisotropic dilation?)

I think we can ignore my original question for the purposes of this PR (because I agree with your plane strain comment). But to answer your question, in plane strain any dilation must be anisotropic, because $\varepsilon_z=0$. Locally, shear bands are pretty much planar, and so any dilation should be uniaxial to first order. In terms of implementation, I don't think this matters, but before you pointed out the deviator() and second_invariant() functions I was reaching for alternative explanations.

Copy link
Member

@gassmoeller gassmoeller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will have to continue this review later, but just a few comments for now.

Comment on lines +1136 to +1227
* $\bar\alpha\gamma$ should be added to the right-hand side of the
* mass conservation equation, where $\bar\alpha$ is the negative
* derivative of plastic potential with respect to the pressure
* ($\sin\psi$ in 2D case), and $\gamma$ is the plastic multiplier.
* The plastic multiplier is given by
* $\gamma = (\tau_{II} - \alpha p - k) / \eta^{ve}$,
* where $\tau_{II}$ is the second invariant of the deviatoric stress,
* $\alpha$ is the negative derivative of yield function with respect to
* the pressure ($\sin\phi$ in 2D case), $k$ is cohesion, and $\eta^{ve}$,
* is the pre-yielding viscosity. When the Picard method or Defect Correction
* Method is applied, the term $\bar\alpha\gamma$ should be split into two
* terms:
* $\bar\alpha\gamma = \bar\alpha\alpha p / \eta^{ve} +
* \bar\alpha(\tau_{II} - k) / \eta^{ve}$,
* the former of which should be moved to the left-hand side in order to
* guarantee the stability of the nonlinear solver. Therefore, this output
* provides two terms: dilation_lhs_term corresponds to
* $\bar\alpha\alpha / \eta^{ve}$ (p is replaced by the shape function),
* and dilation_rhs_term corresponds to $(\tau_{II} - k) / \eta^{ve}$.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this description is pretty specific to the case of plastic dilation, but not the general case of someone prescribing delation because of other processes. Maybe it would be better to limit this documentation to the discussion of where the individual terms will go into the equation, and move the specific parts to drucker_prager.h:145

Comment on lines 154 to 190
compute_dilation_terms_for_stokes_system(const double angle_friction,
const double angle_dilation,
const double cohesion,
const double non_yielding_viscosity,
const double effective_strain_rate) const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you use the following interface instead, this is more in line with that I did in #6384.

Suggested change
compute_dilation_terms_for_stokes_system(const double angle_friction,
const double angle_dilation,
const double cohesion,
const double non_yielding_viscosity,
const double effective_strain_rate) const;
compute_dilation_terms_for_stokes_system(const double angle_friction,
const double angle_dilation,
const double cohesion,
const double non_yielding_viscosity,
const double effective_strain_rate) const;

Comment on lines +111 to +118
/**
* The LHS term corresponding to plastic dilation in the
* Stokes system. For details, see the comments of
* MaterialModel::PrescribedDilation::dilation_lhs_term.
*/
std::vector<double> dilation_lhs_terms;

/**
* The RHS term corresponding to plastic dilation in the
* Stokes system. For details, see the comments of
* MaterialModel::PrescribedDilation::dilation_rhs_term.
*/
std::vector<double> dilation_rhs_terms;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this code part looks different since #6384. Please rebase, the new version will be simpler, because it includes the DruckerPragerParameters structure already, which will automatically include the dilation angle.

// Average among phases
drucker_prager_parameters.angle_internal_friction = MaterialModel::MaterialUtilities::phase_average_value(phase_function_values, n_phase_transitions_per_composition,
angles_internal_friction, composition);
drucker_prager_parameters.angle_dilation = angles_dilation[composition];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldnt you also need to use a call to MaterialModel::MaterialUtilities::phase_average_value to allow different dilation angles for different phases?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot that. It is corrected in the newest commit.

Comment on lines 422 to 432
// Compute the dilation terms if necessary.
if (this->get_parameters().enable_prescribed_dilation == true)
{
if (output_parameters.composition_yielding[j] == true)
{
const double current_dilation = drucker_prager_parameters.angle_dilation * weakening_factors[1];
const std::pair<double,double> dilation_terms = drucker_prager_plasticity.compute_dilation_terms_for_stokes_system (
current_friction,
current_dilation,
current_cohesion,
non_yielding_viscosity,
effective_edot_ii);
output_parameters.dilation_lhs_terms[j] = dilation_terms.first;
output_parameters.dilation_rhs_terms[j] = dilation_terms.second;
}
else
{
output_parameters.dilation_lhs_terms[j] = 0;
output_parameters.dilation_rhs_terms[j] = 0;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we may need to think where to put this code compared to the code above. @naliboff any suggestions?

@YiminJin
Copy link
Contributor Author

Can you raise a GitHub Issue describing the problem?

Sure. I have raised an issue (#6434 ) about this problem.

@YiminJin YiminJin force-pushed the plastic-dilation branch 2 times, most recently from 8fda76d to 35d7af0 Compare June 16, 2025 17:58
Copy link
Member

@gassmoeller gassmoeller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing my earlier comments. I think this code is already in pretty good shape and almost ready to merge. I left just a few comments concerned with optimizing assembly speed and a few requests for more documentation. Let me know when you have addressed these.

volume_fractions,
dilation_values,
composition_dilation_derivatives_wrt_pressure,
1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Comment on lines 176 to 182
( one_over_eta +
// add the dilation LHS term if plastic dilation
// is enabled
( prescribed_dilation != nullptr ?
prescribed_dilation->dilation_lhs_term[q] :
0.0 )
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please do this computation up in line 146 where we compute one_over_eta. E.g.:
const double one_over_eta_plus_dilation = ...

The current loop is one of the most often executed lines in ASPECT, so it is better to move computations and if-branches outside of it.

// consider the derivatives deta/deps
// here, but we leave this as a TODO
one_over_eta
(one_over_eta - dilation_newton_factor)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, here you already precomputated dilation_newton_factor so this can stay as it is.

* (prescribed_dilation->dilation_rhs_term[q] -
prescribed_dilation->dilation_lhs_term[q] *
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this the difference between rhs and lhs term? Since we are assembling the rhs here, I would expect to only see the rhs side term. Please add a comment that explains this above line 464.

Comment on lines 493 to 495
- (prescribed_dilation == nullptr ? 0.0 :
pressure_scaling * pressure_scaling *
prescribed_dilation->dilation_lhs_term[q] *
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

precompute this term outside the loop over i and j.

Comment on lines +474 to +476
- (prescribed_dilation == nullptr ? 0.0 :
pressure_scaling * pressure_scaling *
prescribed_dilation->dilation_lhs_term[q] *
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

precompute this term outside the loop over i and j

Assert(!this->get_parameters().enable_prescribed_dilation
||
outputs.template get_additional_output_object<MaterialModel::PrescribedPlasticDilation<dim>>()->dilation.size()
outputs.template get_additional_output_object<MaterialModel::PrescribedPlasticDilation<dim>>()->dilation_lhs_term.size()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you need to also add an assert for the dilation_rhs_term here? just in case someone accidentally sets them to different sizes.

@YiminJin
Copy link
Contributor Author

@gassmoeller Thank you for the close examination on my codes! The problems you mentioned are addressed now.

Copy link
Member

@gassmoeller gassmoeller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! This looks good to go to me, but I will leave it open for a day to give @naliboff, @bangerth, and @tjhei the chance to comment if they want to.

Can you also add a changelog entry that describes the changes that users will have to do if they wrote their own dilation terms (i.e. that the variable has been renamed and there are now two terms, lhs and rhs).

Copy link
Contributor

@bangerth bangerth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have enough of an understanding of the material models any more to be useful here. I'll let the experts be in charge for this PR :-)

@gassmoeller
Copy link
Member

Since this is blocking #6419 let's merge it.

@gassmoeller gassmoeller merged commit 7bc9ac6 into geodynamics:main Jun 17, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants