Skip to content

Commit a832cf4

Browse files
committed
Implementation of plastic dilation
1 parent a7cfdfe commit a832cf4

File tree

33 files changed

+1031
-306
lines changed

33 files changed

+1031
-306
lines changed

include/aspect/material_model/interface.h

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,15 +1204,27 @@ namespace aspect
12041204
* Stokes solution.
12051205
*
12061206
* This is typically used in a MaterialModel to add dilation when plastic
1207-
* failure occurs as motivated by ChoiPeterson2015. If this output
1208-
* (denoted by R below) is present and enable_prescribed_dilation==true
1209-
* the following terms will be assembled:
1210-
*
1211-
* 1) $\int - (R,q)$ to the conservation of mass equation, creating
1212-
* $-(div u,q) = -(R,q)$.
1213-
* 2) $\int - 2.0 / 3.0 * eta * (R, div v)$ to the RHS of the momentum
1214-
* equation (if the model is incompressible), otherwise this term is
1215-
* already present on the left side.
1207+
* failure occurs, but can be used for other forms of dilation as well.
1208+
* When plastic dilation is included, a term
1209+
* $\bar\alpha\gamma$ should be added to the right-hand side of the
1210+
* mass conservation equation, where $\bar\alpha$ is the negative
1211+
* derivative of plastic potential with respect to the pressure
1212+
* ($\sin\psi$ in 2D case), and $\gamma$ is the plastic multiplier.
1213+
* The plastic multiplier is given by
1214+
* $\gamma = (\tau_{II} - \alpha p - k) / \eta^{ve}$,
1215+
* where $\tau_{II}$ is the second invariant of the deviatoric stress,
1216+
* $\alpha$ is the negative derivative of yield function with respect to
1217+
* the pressure ($\sin\phi$ in 2D case), $k$ is cohesion, and $\eta^{ve}$,
1218+
* is the pre-yielding viscosity. When the Picard method or Defect Correction
1219+
* Method is applied, the term $\bar\alpha\gamma$ should be split into two
1220+
* terms:
1221+
* $\bar\alpha\gamma = \bar\alpha\alpha p / \eta^{ve} +
1222+
* \bar\alpha(\tau_{II} - k) / \eta^{ve}$,
1223+
* the former of which should be moved to the left-hand side in order to
1224+
* guarantee the stability of the nonlinear solver. Therefore, this output
1225+
* provides two terms: dilation_lhs_term corresponds to
1226+
* $\bar\alpha\alpha / \eta^{ve}$ (p is replaced by the shape function),
1227+
* and dilation_rhs_term corresponds to $(\tau_{II} - k) / \eta^{ve}$.
12161228
*/
12171229
template <int dim>
12181230
class PrescribedPlasticDilation : public NamedAdditionalMaterialOutputs<dim>
@@ -1229,10 +1241,16 @@ namespace aspect
12291241
std::vector<double> get_nth_output(const unsigned int idx) const override;
12301242

12311243
/**
1232-
* A scalar value per evaluation point that specifies the prescribed dilation
1233-
* in that point.
1244+
* A scalar value per evaluation point corresponding to the LHS term
1245+
* due to plastic dilation.
1246+
*/
1247+
std::vector<double> dilation_lhs_term;
1248+
1249+
/**
1250+
* A scalar value per evaluation point corresponding to the RHS term
1251+
* due to plastic dilation.
12341252
*/
1235-
std::vector<double> dilation;
1253+
std::vector<double> dilation_rhs_term;
12361254
};
12371255

12381256

include/aspect/material_model/rheology/drucker_prager.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ namespace aspect
4343
*/
4444
double angle_internal_friction;
4545

46+
/**
47+
* Dilation angle (psi) for the current composition and phase
48+
*/
49+
double angle_dilation;
50+
4651
/**
4752
* Cohesion for the current composition and phase
4853
*/
@@ -170,6 +175,20 @@ namespace aspect
170175
compute_derivative (const double angle_internal_friction,
171176
const double effective_strain_rate) const;
172177

178+
/**
179+
* Compute the LHS and RHS dilation terms for the Stokes system.
180+
* LHS: $\bar\alpha\alpha / \eta^{ve}$;
181+
* RHS: $\bar(2\eta^{ve}\varepsilon^{eff} - k) / \eta^{ve}$.
182+
* Here $\alpha$ and $\bar\alpha$ correspond to the friction angle
183+
* and the dilation angle, respectively, $k$ is cohesion,
184+
* $\eta^{ve}$ is the non-yielding viscosity, and $\varepsilon^{eff}$
185+
* is the effective viscosity.
186+
*/
187+
std::pair<double,double>
188+
compute_dilation_terms_for_stokes_system(const DruckerPragerParameters &drucker_prager_parameters,
189+
const double non_yielding_viscosity,
190+
const double effective_strain_rate) const;
191+
173192
private:
174193

175194
/**
@@ -183,6 +202,17 @@ namespace aspect
183202
*/
184203
std::vector<double> angles_internal_friction;
185204

205+
/**
206+
* The plastic potential of the Drucker-Prager model is given by
207+
* tau_II - 6.0 * pressure * sin_psi / (sqrt(3.0) * (3.0 + sin_psi)) in 3D or
208+
* tau_II - pressure * sin_psi in 2D, where tau_II is the second invariant
209+
* of the deviatoric stress.
210+
* Psi is an angle of dilation, that is input by the user in degrees,
211+
* but stored as radians. Note that the dilation angle must not be larger
212+
* than the internal friction angle.
213+
*/
214+
std::vector<double> angles_dilation;
215+
186216
/**
187217
* The cohesion is provided and stored in Pa.
188218
*/

include/aspect/material_model/rheology/visco_plastic.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,20 @@ namespace aspect
102102
* All the drucker prager plasticity parameters.
103103
*/
104104
std::vector<Rheology::DruckerPragerParameters> drucker_prager_parameters;
105+
106+
/**
107+
* The LHS term corresponding to plastic dilation in the
108+
* Stokes system. For details, see the comments of
109+
* MaterialModel::PrescribedDilation::dilation_lhs_term.
110+
*/
111+
std::vector<double> dilation_lhs_terms;
112+
113+
/**
114+
* The RHS term corresponding to plastic dilation in the
115+
* Stokes system. For details, see the comments of
116+
* MaterialModel::PrescribedDilation::dilation_rhs_term.
117+
*/
118+
std::vector<double> dilation_rhs_terms;
105119
};
106120

107121
namespace Rheology
@@ -143,7 +157,7 @@ namespace aspect
143157
*/
144158
void compute_viscosity_derivatives(const unsigned int point_index,
145159
const std::vector<double> &volume_fractions,
146-
const std::vector<double> &composition_viscosities,
160+
const IsostrainViscosities &isostrain_values,
147161
const MaterialModel::MaterialModelInputs<dim> &in,
148162
MaterialModel::MaterialModelOutputs<dim> &out,
149163
const std::vector<double> &phase_function_values = std::vector<double>(),

include/aspect/newton.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,19 @@ namespace aspect
6161
* derivatives when material averaging is applied.
6262
*/
6363
std::vector<double> viscosity_derivative_averaging_weights;
64+
65+
/**
66+
* The derivatives of the plastic dilation with respect to pressure.
67+
* Note that this term does not include $\bar\alpha\alpha / \eta^{ve}$,
68+
* which is always on the left-hand side no matter if the Newton method
69+
* is applied or not.
70+
*/
71+
std::vector<double> dilation_derivative_wrt_pressure;
72+
73+
/**
74+
* The derivatives of the plastic dilation with respect to strain rate.
75+
*/
76+
std::vector<SymmetricTensor<2,dim>> dilation_derivative_wrt_strain_rate;
6477
};
6578
}
6679

include/aspect/simulator/assemblers/stokes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ namespace aspect
4040
void
4141
execute(internal::Assembly::Scratch::ScratchBase<dim> &scratch_base,
4242
internal::Assembly::CopyData::CopyDataBase<dim> &data_base) const override;
43+
44+
void create_additional_material_model_outputs(MaterialModel::MaterialModelOutputs<dim> &outputs) const override;
4345
};
4446

4547
/**

include/aspect/simulator/solver/matrix_free_operators.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ namespace aspect
107107
*/
108108
bool enable_newton_derivatives;
109109

110+
/**
111+
* If true, plastic dilation terms are part of the operator.
112+
*/
113+
bool enable_prescribed_dilation;
114+
110115
/**
111116
* Symmetrize the Newton system when it's true (i.e., the
112117
* stabilization is symmetric or SPD).
@@ -149,6 +154,30 @@ namespace aspect
149154
Table<2, SymmetricTensor<2, dim, VectorizedArray<number>>>
150155
newton_factor_wrt_strain_rate_table;
151156

157+
/**
158+
* Table which stores the dilation LHS terms. For the definition of this
159+
* term, see the comments of MaterialModel::PrescribedPlasticDilation::
160+
* dilation_lhs_term.
161+
*/
162+
Table<2, VectorizedArray<number>> dilation_lhs_term_table;
163+
164+
/**
165+
* Table which stores the product of the plastic dilation derivative
166+
* with respect to pressure and the Newton derivative scaling factor.
167+
* Note that the plastic dilation derivative does not include the term
168+
* $\bar\alpha\alpha / \eta^{ve}$, which is always on the left-hand
169+
* side no matter if the Newton method is applied.
170+
*/
171+
Table<2, VectorizedArray<number>>
172+
dilation_derivative_wrt_pressure_table;
173+
174+
/**
175+
* Table which stores the product of the plastic dilation derivative
176+
* with respect to strain-rate and the Newton derivative scaling factor.
177+
*/
178+
Table<2, SymmetricTensor<2, dim, VectorizedArray<number>>>
179+
dilation_derivative_wrt_strain_rate_table;
180+
152181
/**
153182
* Table which stores the product of the pressure perturbation
154183
* and the normalized gravity. The size is n_face_boundary * n_face_q_points,

source/material_model/interface.cc

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -998,20 +998,45 @@ namespace aspect
998998

999999

10001000

1001+
namespace
1002+
{
1003+
std::vector<std::string> make_prescribed_dilation_outputs_names()
1004+
{
1005+
std::vector<std::string> names;
1006+
names.emplace_back("dilation_lhs_term");
1007+
names.emplace_back("dilation_rhs_term");
1008+
return names;
1009+
}
1010+
}
1011+
1012+
1013+
10011014
template <int dim>
10021015
PrescribedPlasticDilation<dim>::PrescribedPlasticDilation (const unsigned int n_points)
1003-
: NamedAdditionalMaterialOutputs<dim>(std::vector<std::string>(1, "prescribed_dilation")),
1004-
dilation(n_points, numbers::signaling_nan<double>())
1016+
: NamedAdditionalMaterialOutputs<dim>(make_prescribed_dilation_outputs_names()),
1017+
dilation_lhs_term(n_points, numbers::signaling_nan<double>()),
1018+
dilation_rhs_term(n_points, numbers::signaling_nan<double>())
10051019
{}
10061020

10071021

10081022

10091023
template <int dim>
10101024
std::vector<double> PrescribedPlasticDilation<dim>::get_nth_output(const unsigned int idx) const
10111025
{
1012-
(void)idx;
1013-
Assert(idx==0, ExcInternalError());
1014-
return dilation;
1026+
AssertIndexRange (idx, 2);
1027+
switch (idx)
1028+
{
1029+
case 0:
1030+
return dilation_lhs_term;
1031+
1032+
case 1:
1033+
return dilation_rhs_term;
1034+
1035+
default:
1036+
AssertThrow(false, ExcInternalError());
1037+
}
1038+
// we will never get here, so just return something
1039+
return std::vector<double>();
10151040
}
10161041

10171042

source/material_model/rheology/drucker_prager.cc

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ namespace aspect
3434
{
3535
DruckerPragerParameters::DruckerPragerParameters()
3636
: angle_internal_friction (numbers::signaling_nan<double>()),
37-
cohesion (numbers::signaling_nan<double>()),
37+
angle_dilation (numbers::signaling_nan<double>()),
38+
cohesion (numbers::signaling_nan<double>()),
3839
max_yield_stress (numbers::signaling_nan<double>())
3940
{}
4041

@@ -58,6 +59,7 @@ namespace aspect
5859
{
5960
// no phases
6061
drucker_prager_parameters.angle_internal_friction = angles_internal_friction[composition];
62+
drucker_prager_parameters.angle_dilation = angles_dilation[composition];
6163
drucker_prager_parameters.cohesion = cohesions[composition];
6264
drucker_prager_parameters.max_yield_stress = max_yield_stresses[composition];
6365
}
@@ -66,6 +68,8 @@ namespace aspect
6668
// Average among phases
6769
drucker_prager_parameters.angle_internal_friction = MaterialModel::MaterialUtilities::phase_average_value(phase_function_values, n_phase_transitions_per_composition,
6870
angles_internal_friction, composition);
71+
drucker_prager_parameters.angle_dilation = MaterialModel::MaterialUtilities::phase_average_value(phase_function_values, n_phase_transitions_per_composition,
72+
angles_dilation, composition);
6973
drucker_prager_parameters.cohesion = MaterialModel::MaterialUtilities::phase_average_value(phase_function_values, n_phase_transitions_per_composition,
7074
cohesions, composition);
7175
drucker_prager_parameters.max_yield_stress = MaterialModel::MaterialUtilities::phase_average_value(phase_function_values, n_phase_transitions_per_composition,
@@ -220,6 +224,38 @@ namespace aspect
220224

221225

222226

227+
template <int dim>
228+
std::pair<double,double>
229+
DruckerPrager<dim>::compute_dilation_terms_for_stokes_system(const DruckerPragerParameters &drucker_prager_parameters,
230+
const double non_yielding_viscosity,
231+
const double effective_strain_rate) const
232+
{
233+
const double sin_phi = std::sin(drucker_prager_parameters.angle_internal_friction);
234+
const double sin_psi = std::sin(drucker_prager_parameters.angle_dilation);
235+
236+
double alpha;
237+
double alpha_bar;
238+
if (dim == 2)
239+
{
240+
alpha = sin_phi;
241+
alpha_bar = sin_psi;
242+
}
243+
else if (dim == 3)
244+
{
245+
alpha = 6.0 * sin_phi / (std::sqrt(3.0) * (3.0 + sin_phi));
246+
alpha_bar = 6.0 * sin_psi / (std::sqrt(3.0) * (3.0 + sin_psi));
247+
}
248+
else
249+
AssertThrow(false,ExcNotImplemented());
250+
251+
const double dilation_lhs_term = alpha_bar * alpha / non_yielding_viscosity;
252+
const double dilation_rhs_term = alpha_bar * (2. * effective_strain_rate - drucker_prager_parameters.cohesion / non_yielding_viscosity);
253+
254+
return std::make_pair(dilation_lhs_term, dilation_rhs_term);
255+
}
256+
257+
258+
223259
template <int dim>
224260
void
225261
DruckerPrager<dim>::declare_parameters (ParameterHandler &prm)
@@ -231,6 +267,13 @@ namespace aspect
231267
"those corresponding to chemical compositions. "
232268
"For a value of zero, in 2d the von Mises criterion is retrieved. "
233269
"Angles higher than 30 degrees are harder to solve numerically. Units: degrees.");
270+
prm.declare_entry ("Angles of dilation", "0.",
271+
Patterns::Anything(),
272+
"List of angles of plastic dilation, $\\psi$, for background material and compositional fields, "
273+
"for a total of N+1 values, where N is the number of all compositional fields or only "
274+
"those corresponding to chemical compositions. "
275+
"For a value of zero, the von Mises flow rule is retrieved. "
276+
"The dilation angle should never exceed the internal friction angle.");
234277
prm.declare_entry ("Cohesions", "1e20",
235278
Patterns::Anything(),
236279
"List of cohesions, $C$, for background material and compositional fields, "
@@ -290,9 +333,26 @@ namespace aspect
290333
angles_internal_friction = Utilities::MapParsing::parse_map_to_double_array(prm.get("Angles of internal friction"),
291334
options);
292335

336+
options.property_name = "Angles of dilation";
337+
angles_dilation = Utilities::MapParsing::parse_map_to_double_array(prm.get("Angles of dilation"),
338+
options);
339+
293340
// Convert angles from degrees to radians
294-
for (double &angle : angles_internal_friction)
295-
angle *= constants::degree_to_radians;
341+
for (unsigned int i = 0; i < angles_internal_friction.size(); ++i)
342+
{
343+
angles_internal_friction[i] *= constants::degree_to_radians;
344+
angles_dilation[i] *= constants::degree_to_radians;
345+
346+
AssertThrow(angles_dilation[i] <= angles_internal_friction[i],
347+
ExcMessage("The dilation angle is greater than the internal friction angle for "
348+
"composition " + Utilities::to_string(i) + "."));
349+
350+
if (angles_dilation[i] > 0.0)
351+
AssertThrow(this->get_parameters().enable_prescribed_dilation == true,
352+
ExcMessage("ASPECT detected a nonzero dilation angle, but dilation is "
353+
"not enabled. Please set parameter entry 'Enable prescribed "
354+
"dilation' to 'true'."));
355+
}
296356

297357
options.property_name = "Cohesions";
298358
cohesions = Utilities::MapParsing::parse_map_to_double_array(prm.get("Cohesions"),

0 commit comments

Comments
 (0)