Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 603bf73

Browse files
committedJun 6, 2024·
addressed comments
1 parent 39f923e commit 603bf73

File tree

2 files changed

+38
-31
lines changed

2 files changed

+38
-31
lines changed
 

‎include/aspect/material_model/rheology/diffusion_dislocation.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include <aspect/material_model/rheology/diffusion_creep.h>
2929
#include <aspect/material_model/rheology/dislocation_creep.h>
3030

31+
#include <deal.II/sundials/kinsol.h>
32+
3133
namespace aspect
3234
{
3335
namespace MaterialModel
@@ -100,8 +102,8 @@ namespace aspect
100102
const double current_log_stress_ii,
101103
const double pressure,
102104
const double temperature,
103-
const Rheology::DiffusionCreepParameters diffusion_creep_parameters,
104-
const Rheology::DislocationCreepParameters dislocation_creep_parameters,
105+
const Rheology::DiffusionCreepParameters &diffusion_creep_parameters,
106+
const Rheology::DislocationCreepParameters &dislocation_creep_parameters,
105107
const double log_edot_ii) const;
106108

107109
/**
@@ -144,6 +146,7 @@ namespace aspect
144146
unsigned int n_chemical_composition_fields;
145147

146148
MaterialUtilities::CompositionalAveragingOperation viscosity_averaging;
149+
SUNDIALS::KINSOL<Vector<double>>::AdditionalData kinsol_settings;
147150

148151
};
149152

‎source/material_model/rheology/diffusion_dislocation.cc

+33-29
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include <aspect/material_model/utilities.h>
2424
#include <aspect/utilities.h>
2525

26-
#include <deal.II/sundials/kinsol.h>
2726
#include <deal.II/base/signaling_nan.h>
2827
#include <deal.II/base/parameter_handler.h>
2928

@@ -55,14 +54,16 @@ namespace aspect
5554
const double edot_ii = std::max(std::sqrt(std::max(-second_invariant(deviator(strain_rate)), 0.)),
5655
min_strain_rate);
5756
const double log_edot_ii = std::log(edot_ii);
58-
double log_strain_rate_deriv;
5957

6058
// Find effective viscosities for each of the individual phases
6159
// Viscosities should have the same number of entries as compositional fields
6260
std::vector<double> composition_viscosities(n_chemical_composition_fields);
6361
for (unsigned int j=0; j < n_chemical_composition_fields; ++j)
6462
{
65-
// Power law creep equation
63+
// Because the ratios of the diffusion and dislocation strain rates are not known, stress is also unknown
64+
// We use KINSOL to find the second invariant of the stress tensor that satisfies the total strain rate.
65+
66+
// The power law creep equation is
6667
// edot_ii_i = A_i * stress_ii_i^{n_i} * d^{-m} \exp\left(-\frac{E_i^\ast + PV_i^\ast}{n_iRT}\right)
6768
// where ii indicates the square root of the second invariant and
6869
// i corresponds to diffusion or dislocation creep
@@ -73,22 +74,9 @@ namespace aspect
7374
// For dislocation creep, viscosity is grain size independent (m=0)
7475
const Rheology::DislocationCreepParameters dislocation_creep_parameters = dislocation_creep.compute_creep_parameters(j);
7576

76-
// For diffusion creep, viscosity is grain size dependent
77-
const double prefactor_stress_diffusion = diffusion_creep_parameters.prefactor *
78-
std::pow(grain_size, -diffusion_creep_parameters.grain_size_exponent) *
79-
std::exp(-(std::max(diffusion_creep_parameters.activation_energy + pressure*diffusion_creep_parameters.activation_volume,0.0))/
80-
(constants::gas_constant*temperature));
81-
82-
// Because the ratios of the diffusion and dislocation strain rates are not known, stress is also unknown
83-
// We use KINSOL to find the second invariant of the stress tensor that satisfies the total strain rate.
84-
SUNDIALS::KINSOL<Vector<double>>::AdditionalData additional_data;
85-
additional_data.strategy = dealii::SUNDIALS::KINSOL<>::AdditionalData::newton;
86-
additional_data.function_tolerance = log_strain_rate_residual_threshold;
87-
additional_data.maximum_non_linear_iterations = stress_max_iteration_number;
88-
additional_data.maximum_setup_calls = 1;
89-
90-
SUNDIALS::KINSOL<Vector<double>> nonlinear_solver(additional_data);
9177

78+
SUNDIALS::KINSOL<Vector<double>> nonlinear_solver(kinsol_settings);
79+
double log_strain_rate_deriv;
9280
nonlinear_solver.reinit_vector = [&](Vector<double> &x)
9381
{
9482
x.reinit(1);
@@ -98,7 +86,9 @@ namespace aspect
9886
[&](const Vector<double> &current_log_stress_ii,
9987
Vector<double> &residual)
10088
{
101-
std::tie(residual(0), log_strain_rate_deriv) = compute_log_strain_rate_residual_and_derivative(current_log_stress_ii[0], pressure, temperature, diffusion_creep_parameters, dislocation_creep_parameters, log_edot_ii);
89+
std::tie(residual(0), log_strain_rate_deriv) = compute_log_strain_rate_residual_and_derivative(
90+
current_log_stress_ii[0], pressure, temperature, diffusion_creep_parameters, dislocation_creep_parameters, log_edot_ii
91+
);
10292
};
10393

10494
nonlinear_solver.setup_jacobian =
@@ -115,14 +105,23 @@ namespace aspect
115105
solution(0) = residual(0) / log_strain_rate_deriv;
116106
};
117107

118-
// Start with the assumption that all strain is accommodated by diffusion creep:
119-
// If the diffusion creep prefactor is very small, that means that the diffusion viscosity is very large.
120-
// In this case, use the maximum viscosity instead to compute the starting guess.
121-
double stress_ii = (prefactor_stress_diffusion > (0.5 / maximum_viscosity)
122-
?
123-
edot_ii/prefactor_stress_diffusion
124-
:
125-
0.5 / maximum_viscosity);
108+
109+
// Our starting guess for the stress assumes that all strain is
110+
// accommodated by either diffusion creep, dislocation creep,
111+
// or by the maximum viscosity limiter.
112+
const double prefactor_stress_diffusion = diffusion_creep_parameters.prefactor *
113+
std::pow(grain_size, -diffusion_creep_parameters.grain_size_exponent) *
114+
std::exp(-(std::max(diffusion_creep_parameters.activation_energy + pressure*diffusion_creep_parameters.activation_volume,0.0))/
115+
(constants::gas_constant*temperature));
116+
117+
const double prefactor_stress_dislocation = dislocation_creep_parameters.prefactor *
118+
std::exp(-(std::max(dislocation_creep_parameters.activation_energy + pressure*dislocation_creep_parameters.activation_volume,0.0))/
119+
(constants::gas_constant*temperature));
120+
121+
double stress_ii = std::min({
122+
std::pow(edot_ii/prefactor_stress_diffusion, 1./diffusion_creep_parameters.stress_exponent),
123+
std::pow(edot_ii/prefactor_stress_dislocation, 1./dislocation_creep_parameters.stress_exponent),
124+
0.5 / maximum_viscosity});
126125

127126
// KINSOL works on vectors and so the scalar (log) stress is inserted into
128127
// a vector of length 1
@@ -142,8 +141,8 @@ namespace aspect
142141
const double current_log_stress_ii,
143142
const double pressure,
144143
const double temperature,
145-
const Rheology::DiffusionCreepParameters diffusion_creep_parameters,
146-
const Rheology::DislocationCreepParameters dislocation_creep_parameters,
144+
const Rheology::DiffusionCreepParameters &diffusion_creep_parameters,
145+
const Rheology::DislocationCreepParameters &dislocation_creep_parameters,
147146
const double log_edot_ii) const
148147
{
149148
const std::pair<double, double> log_diff_edot_and_deriv = diffusion_creep.compute_log_strain_rate_and_derivative(current_log_stress_ii, pressure, temperature, diffusion_creep_parameters);
@@ -339,6 +338,11 @@ namespace aspect
339338
dislocation_creep.initialize_simulator (this->get_simulator());
340339
dislocation_creep.parse_parameters(prm, std::make_unique<std::vector<unsigned int>>(n_chemical_composition_fields));
341340

341+
// KINSOL settings
342+
kinsol_settings.strategy = dealii::SUNDIALS::KINSOL<>::AdditionalData::newton;
343+
kinsol_settings.function_tolerance = log_strain_rate_residual_threshold;
344+
kinsol_settings.maximum_non_linear_iterations = stress_max_iteration_number;
345+
kinsol_settings.maximum_setup_calls = 1;
342346
}
343347
}
344348
}

0 commit comments

Comments
 (0)
Please sign in to comment.