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 97d618f

Browse files
committedJun 5, 2024·
merge residual and jacobian calculation
1 parent 26cfcc0 commit 97d618f

File tree

2 files changed

+43
-73
lines changed

2 files changed

+43
-73
lines changed
 

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

+8-21
Original file line numberDiff line numberDiff line change
@@ -90,32 +90,19 @@ namespace aspect
9090
const double temperature,
9191
const SymmetricTensor<2,dim> &strain_rate) const;
9292

93-
/**
94-
* Compute the derivative of the natural logarithm of the strain rate
95-
* with respect to the natural logarithm of the stress
96-
* at the current evaluation point (log stress) estimated by KINSOL.
97-
*/
98-
void
99-
compute_log_strain_rate_deriv(const Vector<double> &evaluation_point,
100-
double pressure,
101-
double temperature,
102-
const Rheology::DiffusionCreepParameters diffusion_creep_parameters,
103-
const Rheology::DislocationCreepParameters dislocation_creep_parameters,
104-
double &log_strain_rate_deriv) const;
105-
10693
/**
10794
* Compute the residual of the natural logarithm of the strain rate
108-
* at the current evaluation point (log stress) estimated by KINSOL.
95+
* and the derivative with respect to the logarithm of the stress
96+
* at the current value of the logarithm of the stress.
10997
*/
110-
void
111-
compute_log_strain_rate_residual(
112-
const Vector<double> &evaluation_point,
113-
Vector<double> &residual,
114-
double pressure,
115-
double temperature,
98+
std::pair<double, double>
99+
compute_log_strain_rate_residual_and_derivative(
100+
const double current_log_stress_ii,
101+
const double pressure,
102+
const double temperature,
116103
const Rheology::DiffusionCreepParameters diffusion_creep_parameters,
117104
const Rheology::DislocationCreepParameters dislocation_creep_parameters,
118-
double log_edot_ii) const;
105+
const double log_edot_ii) const;
119106

120107
/**
121108
* Compute the viscosity based on the composite viscous creep law,

‎source/material_model/rheology/diffusion_dislocation.cc

+35-52
Original file line numberDiff line numberDiff line change
@@ -80,20 +80,11 @@ namespace aspect
8080
(constants::gas_constant*temperature));
8181

8282
// 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.
84-
// Start with the assumption that all strain is accommodated by diffusion creep:
85-
// If the diffusion creep prefactor is very small, that means that the diffusion viscosity is very large.
86-
// In this case, use the maximum viscosity instead to compute the starting guess.
87-
double stress_ii = (prefactor_stress_diffusion > (0.5 / maximum_viscosity)
88-
?
89-
edot_ii/prefactor_stress_diffusion
90-
:
91-
0.5 / maximum_viscosity);
92-
Vector<double> log_stress_ii(1);
93-
log_stress_ii[0] = std::log(stress_ii);
94-
95-
typename SUNDIALS::KINSOL<Vector<double>>::AdditionalData additional_data;
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;
9685
additional_data.function_tolerance = log_strain_rate_residual_threshold;
86+
additional_data.maximum_non_linear_iterations = stress_max_iteration_number;
87+
additional_data.maximum_setup_calls = 1;
9788

9889
SUNDIALS::KINSOL<Vector<double>> nonlinear_solver(additional_data);
9990

@@ -103,74 +94,66 @@ namespace aspect
10394
};
10495

10596
nonlinear_solver.residual =
106-
[&](const Vector<double> &evaluation_point,
97+
[&](const Vector<double> &current_log_stress_ii,
10798
Vector<double> &residual)
10899
{
109-
compute_log_strain_rate_residual(evaluation_point, residual, pressure, temperature, diffusion_creep_parameters, dislocation_creep_parameters, log_edot_ii);
100+
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);
110101
};
111102

112103
nonlinear_solver.setup_jacobian =
113-
[&](const Vector<double> &current_u,
104+
[&](const Vector<double> & /*current_log_stress_ii*/,
114105
const Vector<double> & /*current_f*/)
115106
{
116-
compute_log_strain_rate_deriv(current_u, pressure, temperature, diffusion_creep_parameters, dislocation_creep_parameters, log_strain_rate_deriv);
107+
// Do nothing here, because we calculate the Jacobian in the residual function
117108
};
118109

119-
nonlinear_solver.solve_with_jacobian = [&](const Vector<double> &rhs,
110+
nonlinear_solver.solve_with_jacobian = [&](const Vector<double> &residual,
120111
Vector<double> &solution,
121112
const double /*tolerance*/)
122113
{
123-
solution(0) -= rhs(0)/log_strain_rate_deriv;
114+
solution(0) = residual(0) / log_strain_rate_deriv;
124115
};
125116

126-
nonlinear_solver.solve(log_stress_ii);
117+
// Start with the assumption that all strain is accommodated by diffusion creep:
118+
// If the diffusion creep prefactor is very small, that means that the diffusion viscosity is very large.
119+
// In this case, use the maximum viscosity instead to compute the starting guess.
120+
double stress_ii = (prefactor_stress_diffusion > (0.5 / maximum_viscosity)
121+
?
122+
edot_ii/prefactor_stress_diffusion
123+
:
124+
0.5 / maximum_viscosity);
127125

126+
// KINSOL works on vectors and so the scalar (log) stress is inserted into
127+
// a vector of length 1
128+
Vector<double> log_stress_ii(1);
129+
log_stress_ii[0] = std::log(stress_ii);
130+
131+
nonlinear_solver.solve(log_stress_ii);
128132
stress_ii = std::exp(log_stress_ii[0]);
129133
composition_viscosities[j] = std::min(std::max(stress_ii/edot_ii/2, minimum_viscosity), maximum_viscosity);
130134
}
131135
return composition_viscosities;
132136
}
133137

134-
135138
template <int dim>
136-
void
137-
DiffusionDislocation<dim>::compute_log_strain_rate_deriv(
138-
const Vector<double> &evaluation_point,
139-
double pressure,
140-
double temperature,
141-
const Rheology::DiffusionCreepParameters diffusion_creep_parameters,
142-
const Rheology::DislocationCreepParameters dislocation_creep_parameters,
143-
double &log_strain_rate_deriv) const
144-
{
145-
const std::pair<double, double> log_diff_edot_and_deriv = diffusion_creep.compute_log_strain_rate_and_derivative(evaluation_point[0], pressure, temperature, diffusion_creep_parameters);
146-
const std::pair<double, double> log_disl_edot_and_deriv = dislocation_creep.compute_log_strain_rate_and_derivative(evaluation_point[0], pressure, temperature, dislocation_creep_parameters);
147-
148-
const double strain_rate_diffusion = std::exp(log_diff_edot_and_deriv.first);
149-
const double strain_rate_dislocation = std::exp(log_disl_edot_and_deriv.first);
150-
log_strain_rate_deriv = (strain_rate_diffusion * log_diff_edot_and_deriv.second + strain_rate_dislocation * log_disl_edot_and_deriv.second)/
151-
(strain_rate_diffusion + strain_rate_dislocation);
152-
}
153-
154-
155-
156-
template <int dim>
157-
void
158-
DiffusionDislocation<dim>::compute_log_strain_rate_residual(
159-
const Vector<double> &evaluation_point,
160-
Vector<double> &residual,
161-
double pressure,
162-
double temperature,
139+
std::pair<double, double>
140+
DiffusionDislocation<dim>::compute_log_strain_rate_residual_and_derivative(
141+
const double current_log_stress_ii,
142+
const double pressure,
143+
const double temperature,
163144
const Rheology::DiffusionCreepParameters diffusion_creep_parameters,
164145
const Rheology::DislocationCreepParameters dislocation_creep_parameters,
165-
double log_edot_ii) const
146+
const double log_edot_ii) const
166147
{
167-
const std::pair<double, double> log_diff_edot_and_deriv = diffusion_creep.compute_log_strain_rate_and_derivative(evaluation_point[0], pressure, temperature, diffusion_creep_parameters);
168-
const std::pair<double, double> log_disl_edot_and_deriv = dislocation_creep.compute_log_strain_rate_and_derivative(evaluation_point[0], pressure, temperature, dislocation_creep_parameters);
148+
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);
149+
const std::pair<double, double> log_disl_edot_and_deriv = dislocation_creep.compute_log_strain_rate_and_derivative(current_log_stress_ii, pressure, temperature, dislocation_creep_parameters);
169150

170151
const double strain_rate_diffusion = std::exp(log_diff_edot_and_deriv.first);
171152
const double strain_rate_dislocation = std::exp(log_disl_edot_and_deriv.first);
153+
double log_strain_rate_deriv = (strain_rate_diffusion * log_diff_edot_and_deriv.second + strain_rate_dislocation * log_disl_edot_and_deriv.second)/
154+
(strain_rate_diffusion + strain_rate_dislocation);
172155
const double log_strain_rate_iterate = std::log(strain_rate_diffusion + strain_rate_dislocation);
173-
residual(0) = log_edot_ii - log_strain_rate_iterate;
156+
return std::make_pair(log_strain_rate_iterate - log_edot_ii, log_strain_rate_deriv);
174157
}
175158

176159
template <int dim>

0 commit comments

Comments
 (0)
Please sign in to comment.