Skip to content

Commit 5bb559c

Browse files
committed
make deviator() and second_invariant() consistent with plane strain assumption in 2D
1 parent 72eee6c commit 5bb559c

24 files changed

+122
-58
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Changed: The deviator and second invariant of symmetric tensors are modified to
2+
be consistent with the plane strain assumption in 2D. It changes the outputs of
3+
compressible material models that are dependent on the deviatoric strain rate.
4+
<br>
5+
(Yimin Jin, 2025/06/17)

include/aspect/utilities.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,38 @@ namespace aspect
14071407
// Declare the existence of a specialization:
14081408
template <>
14091409
const Tensor<3,3> &levi_civita<3>();
1410+
1411+
/**
1412+
* Compute the deviator of a symmetric tensor. This function is equivalent to
1413+
* dealii::deviator in 3D, while in 2D it is consistent with the plane strain assumption.
1414+
* Specifically, the deviator of the stress tensor $\mathbf\tau$ in 2D is given by
1415+
* $\text{dev}(\mathbf\tau) = \mathbf\tau - \frac{1}{3}\text{trace}(\mathbf\tau)\mathbf 1$
1416+
* under the plane strain assumption.
1417+
*
1418+
* It should be noted that the consistent deviator of a consistently deviatoric tensor is
1419+
* not itself in 2D, which implies that it is invalid to apply this function to a symmetric
1420+
* tensor more than once.
1421+
*/
1422+
template <int dim>
1423+
SymmetricTensor<2,dim>
1424+
consistent_deviator(const SymmetricTensor<2,dim> &input);
1425+
1426+
/**
1427+
* Compute the second invariant of a deviatoric tensor of rank 2. This function is
1428+
* equivalent to dealii::second_invariant in 3D, while in 2D it is consistent with the
1429+
* plane strain assumption. Specifically, the second invariant of the deviatoric
1430+
* stress tensor $\tau_{II}$ in 2D is given by $\tau_{II} = -\frac{1}{2}(\tau_{11}^2 +
1431+
* \tau_{22}^2 + \tau_{33}^2 + 2\tau_{12}^2) = -\frac{1}{2}[\tau_{11}^2 + \tau_{22}^2 +
1432+
* (\tau_{11} + \tau_{22})^2 + 2\tau_{12}^2]$ under the plane strain assumption.
1433+
*
1434+
* It should be noted that this function provides the correct result in 2D only when the
1435+
* input tensor is deviatoric in the sense of plane strain, which cannot be examined
1436+
* without extra information (the trace of a plane strain deviatoric tensor is not
1437+
* zero). Thus, extra care must be taken when using this function.
1438+
*/
1439+
template <int dim>
1440+
double
1441+
consistent_second_invariant_of_deviatoric_tensor(const SymmetricTensor<2,dim> &input);
14101442
}
14111443

14121444
}

source/heating_model/shear_heating.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ namespace aspect
7676
drucker_prager_parameters);
7777

7878
// Scale the stress accordingly.
79-
const double deviatoric_stress = 2 * material_model_outputs.viscosities[q] * std::sqrt(std::fabs(second_invariant(deviatoric_strain_rate)));
79+
const double deviatoric_stress = 2 * material_model_outputs.viscosities[q] * std::sqrt(std::fabs(Utilities::Tensors::consistent_second_invariant_of_deviatoric_tensor(deviatoric_strain_rate)));
8080
double scaling_factor = 1.0;
8181
if (deviatoric_stress > 0.0)
8282
scaling_factor = std::min(yield_stress / deviatoric_stress, 1.0);

source/material_model/drucker_prager.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ namespace aspect
5353
Assert(std::isfinite(in.strain_rate[i].norm()),
5454
ExcMessage("Invalid strain_rate in the MaterialModelInputs. This is likely because it was "
5555
"not filled by the caller."));
56-
const SymmetricTensor<2,dim> strain_rate_deviator = deviator(in.strain_rate[i]);
56+
const SymmetricTensor<2,dim> strain_rate_deviator = Utilities::Tensors::consistent_deviator(in.strain_rate[i]);
5757

5858
// For the very first time this function is called
5959
// (the first iteration of the first timestep), this function is called
@@ -64,8 +64,8 @@ namespace aspect
6464
// In later iterations and timesteps we calculate the second moment
6565
// invariant of the deviatoric strain rate tensor.
6666
// This is equal to the negative of the second principle
67-
// invariant of the deviatoric strain rate (calculated with the function second_invariant),
68-
// as shown in Appendix A of Zienkiewicz and Taylor (Solid Mechanics, 2000).
67+
// invariant of the deviatoric strain rate, as shown in Appendix A of
68+
// Zienkiewicz and Taylor (Solid Mechanics, 2000).
6969
//
7070
// The negative of the second principle invariant is equal to 0.5 e_dot_dev_ij e_dot_dev_ji,
7171
// where e_dot_dev is the deviatoric strain rate tensor. The square root of this quantity
@@ -78,7 +78,7 @@ namespace aspect
7878
// initialized. This might mean that we are
7979
// in a unit test, or at least that we can't
8080
// rely on any simulator information
81-
std::fabs(second_invariant(strain_rate_deviator))
81+
std::fabs(Utilities::Tensors::consistent_second_invariant_of_deviatoric_tensor(strain_rate_deviator))
8282
:
8383
// simulator object is available, but we need to treat the
8484
// first time step separately
@@ -88,7 +88,7 @@ namespace aspect
8888
?
8989
reference_strain_rate * reference_strain_rate
9090
:
91-
std::fabs(second_invariant(strain_rate_deviator))));
91+
std::fabs(Utilities::Tensors::consistent_second_invariant_of_deviatoric_tensor(strain_rate_deviator))));
9292

9393
const double strain_rate_effective = edot_ii_strict;
9494

source/material_model/entropy_model.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ namespace aspect
253253
drucker_prager_parameters);
254254
}
255255

256-
const double strain_rate_effective = std::fabs(second_invariant(deviator(in.strain_rate[i])));
256+
const double strain_rate_effective = std::fabs(Utilities::Tensors::consistent_second_invariant_of_deviatoric_tensor(Utilities::Tensors::consistent_deviator(in.strain_rate[i])));
257257

258258
if (std::sqrt(strain_rate_effective) >= std::numeric_limits<double>::min())
259259
{

source/material_model/grain_size.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ namespace aspect
198198
}
199199

200200
const double strain_rate_dependence = (1.0 - dislocation_creep_exponent[phase_index]) / dislocation_creep_exponent[phase_index];
201-
const SymmetricTensor<2,dim> shear_strain_rate = strain_rate - 1./dim * trace(strain_rate) * unit_symmetric_tensor<dim>();
202-
const double second_strain_rate_invariant = std::sqrt(std::max(-second_invariant(shear_strain_rate), 0.));
201+
const SymmetricTensor<2,dim> shear_strain_rate = Utilities::Tensors::consistent_deviator(strain_rate);
202+
const double second_strain_rate_invariant = std::sqrt(std::max(-Utilities::Tensors::consistent_second_invariant_of_deviatoric_tensor(shear_strain_rate), 0.));
203203

204204
// If the strain rate is zero, the dislocation viscosity is infinity.
205205
if (second_strain_rate_invariant <= std::numeric_limits<double>::min())
@@ -221,7 +221,7 @@ namespace aspect
221221
{
222222
const SymmetricTensor<2,dim> dislocation_strain_rate = diffusion_viscosity
223223
/ (diffusion_viscosity + dis_viscosity) * shear_strain_rate;
224-
const double dislocation_strain_rate_invariant = std::sqrt(std::max(-second_invariant(dislocation_strain_rate), 0.));
224+
const double dislocation_strain_rate_invariant = std::sqrt(std::max(-Utilities::Tensors::consistent_second_invariant_of_deviatoric_tensor(dislocation_strain_rate), 0.));
225225

226226
dis_viscosity_old = dis_viscosity;
227227
dis_viscosity = dislocation_creep_prefactor[phase_index]
@@ -540,8 +540,8 @@ namespace aspect
540540
Assert(std::isfinite(in.strain_rate[i].norm()),
541541
ExcMessage("Invalid strain_rate in the MaterialModelInputs. This is likely because it was "
542542
"not filled by the caller."));
543-
const SymmetricTensor<2,dim> shear_strain_rate = deviator(in.strain_rate[i]);
544-
const double second_strain_rate_invariant = std::sqrt(std::max(-second_invariant(shear_strain_rate), 0.));
543+
const SymmetricTensor<2,dim> shear_strain_rate = Utilities::Tensors::consistent_deviator(in.strain_rate[i]);
544+
const double second_strain_rate_invariant = std::sqrt(std::max(-Utilities::Tensors::consistent_second_invariant_of_deviatoric_tensor(shear_strain_rate), 0.));
545545

546546
const double adiabatic_temperature = this->get_adiabatic_conditions().is_initialized()
547547
?

source/material_model/reaction_model/grain_size_evolution.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,8 @@ namespace aspect
226226
std::pow(roughness_to_grain_size, m);
227227

228228
// grain size reduction in dislocation creep regime
229-
const SymmetricTensor<2,dim> shear_strain_rate = in.strain_rate[i] - 1./dim * trace(in.strain_rate[i]) * unit_symmetric_tensor<dim>();
230-
const double second_strain_rate_invariant = std::sqrt(std::max(-second_invariant(shear_strain_rate), 0.));
229+
const SymmetricTensor<2,dim> shear_strain_rate = Utilities::Tensors::consistent_deviator(in.strain_rate[i]);
230+
const double second_strain_rate_invariant = std::sqrt(std::max(-Utilities::Tensors::consistent_second_invariant_of_deviatoric_tensor(shear_strain_rate), 0.));
231231

232232
const double current_diffusion_viscosity = diffusion_viscosity(in.temperature[i], adiabatic_temperature, pressures[i], grain_size, second_strain_rate_invariant, phase_indices[i]);
233233
current_dislocation_viscosity = dislocation_viscosity(in.temperature[i], adiabatic_temperature, pressures[i], in.strain_rate[i], phase_indices[i], current_diffusion_viscosity, current_dislocation_viscosity);

source/material_model/rheology/composite_visco_plastic.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ namespace aspect
161161
// to prevent a division-by-zero, and a floating point exception.
162162
// Otherwise, calculate the square-root of the norm of the second invariant of the deviatoric-
163163
// strain rate (often simplified as epsilondot_ii)
164-
const double edot_ii = std::max(std::sqrt(std::max(-second_invariant(deviator(strain_rate)), 0.)),
164+
const double edot_ii = std::max(std::sqrt(std::max(-Utilities::Tensors::consistent_second_invariant_of_deviatoric_tensor(Utilities::Tensors::consistent_deviator(strain_rate)), 0.)),
165165
minimum_strain_rate);
166166
const double log_edot_ii = std::log(edot_ii);
167167

@@ -475,7 +475,7 @@ namespace aspect
475475
// to prevent a division-by-zero, and a floating point exception.
476476
// Otherwise, calculate the square-root of the norm of the second invariant of the deviatoric-
477477
// strain rate (often simplified as epsilondot_ii)
478-
const double edot_ii = std::max(std::sqrt(std::max(-second_invariant(deviator(strain_rate)), 0.)),
478+
const double edot_ii = std::max(std::sqrt(std::max(-Utilities::Tensors::consistent_second_invariant_of_deviatoric_tensor(Utilities::Tensors::consistent_deviator(strain_rate)), 0.)),
479479
minimum_strain_rate);
480480
const double log_edot_ii = std::log(edot_ii);
481481

source/material_model/rheology/diffusion_dislocation.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ namespace aspect
5151
// to prevent a division-by-zero, and a floating point exception.
5252
// Otherwise, calculate the square-root of the norm of the second invariant of the deviatoric-
5353
// strain rate (often simplified as epsilondot_ii)
54-
const double edot_ii = std::max(std::sqrt(std::max(-second_invariant(deviator(strain_rate)), 0.)),
54+
const double edot_ii = std::max(std::sqrt(std::max(-Utilities::Tensors::consistent_second_invariant_of_deviatoric_tensor(Utilities::Tensors::consistent_deviator(strain_rate)), 0.)),
5555
min_strain_rate);
5656
const double log_edot_ii = std::log(edot_ii);
5757

source/material_model/rheology/elasticity.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ namespace aspect
401401

402402
for (unsigned int i=0; i < in.n_evaluation_points(); ++i)
403403
{
404-
const SymmetricTensor<2, dim> deviatoric_strain_rate = deviator(in.strain_rate[i]);
404+
const SymmetricTensor<2, dim> deviatoric_strain_rate = Utilities::Tensors::consistent_deviator(in.strain_rate[i]);
405405

406406
// Get stress from timestep $t$ rotated and advected into the current
407407
// timestep $t+\Delta t_c$ from the compositional fields.
@@ -496,7 +496,7 @@ namespace aspect
496496
for (unsigned int i = 0; i < in.n_evaluation_points(); ++i)
497497
{
498498
const double eta = out.viscosities[i];
499-
const SymmetricTensor<2, dim> deviatoric_strain_rate = deviator(in.strain_rate[i]);
499+
const SymmetricTensor<2, dim> deviatoric_strain_rate = Utilities::Tensors::consistent_deviator(in.strain_rate[i]);
500500
const SymmetricTensor<2,dim> stress_0_advected (Utilities::Tensors::to_symmetric_tensor<dim>(&in.composition[i][stress_start_index],
501501
&in.composition[i][stress_start_index]+n_independent_components));
502502
const SymmetricTensor<2,dim> stress_old (Utilities::Tensors::to_symmetric_tensor<dim>(&in.composition[i][stress_start_index+n_independent_components],
@@ -700,7 +700,7 @@ namespace aspect
700700

701701
// Compute the total stress at time t.
702702
const SymmetricTensor<2, dim>
703-
stress_t = 2. * effective_creep_viscosity * deviator(in.strain_rate[i])
703+
stress_t = 2. * effective_creep_viscosity * Utilities::Tensors::consistent_deviator(in.strain_rate[i])
704704
+ effective_creep_viscosity / elastic_viscosity * stress_0_t
705705
+ (1. - timestep_ratio) * (1. - effective_creep_viscosity / elastic_viscosity) * stress_old;
706706

@@ -858,7 +858,7 @@ namespace aspect
858858
const double timestep_ratio = calculate_timestep_ratio();
859859

860860
const SymmetricTensor<2, dim>
861-
edot_deviator = deviator(strain_rate) + 0.5 * stress_0_advected / elastic_viscosity
861+
edot_deviator = strain_rate + 0.5 * stress_0_advected / elastic_viscosity
862862
+ 0.5 * (1. - timestep_ratio) * (1. - creep_viscosity/elastic_viscosity) * stress_old / creep_viscosity;
863863

864864
return edot_deviator;

0 commit comments

Comments
 (0)