@@ -80,20 +80,11 @@ namespace aspect
80
80
(constants::gas_constant*temperature));
81
81
82
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.
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;
96
85
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 ;
97
88
98
89
SUNDIALS::KINSOL<Vector<double >> nonlinear_solver (additional_data);
99
90
@@ -103,74 +94,66 @@ namespace aspect
103
94
};
104
95
105
96
nonlinear_solver.residual =
106
- [&](const Vector<double > &evaluation_point ,
97
+ [&](const Vector<double > ¤t_log_stress_ii ,
107
98
Vector<double > &residual)
108
99
{
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);
110
101
};
111
102
112
103
nonlinear_solver.setup_jacobian =
113
- [&](const Vector<double > ¤t_u ,
104
+ [&](const Vector<double > & /* current_log_stress_ii */ ,
114
105
const Vector<double > & /* current_f*/ )
115
106
{
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
117
108
};
118
109
119
- nonlinear_solver.solve_with_jacobian = [&](const Vector<double > &rhs ,
110
+ nonlinear_solver.solve_with_jacobian = [&](const Vector<double > &residual ,
120
111
Vector<double > &solution,
121
112
const double /* tolerance*/ )
122
113
{
123
- solution (0 ) -= rhs (0 )/ log_strain_rate_deriv;
114
+ solution (0 ) = residual (0 ) / log_strain_rate_deriv;
124
115
};
125
116
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);
127
125
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);
128
132
stress_ii = std::exp (log_stress_ii[0 ]);
129
133
composition_viscosities[j] = std::min (std::max (stress_ii/edot_ii/2 , minimum_viscosity), maximum_viscosity);
130
134
}
131
135
return composition_viscosities;
132
136
}
133
137
134
-
135
138
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,
163
144
const Rheology::DiffusionCreepParameters diffusion_creep_parameters,
164
145
const Rheology::DislocationCreepParameters dislocation_creep_parameters,
165
- double log_edot_ii) const
146
+ const double log_edot_ii) const
166
147
{
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);
169
150
170
151
const double strain_rate_diffusion = std::exp (log_diff_edot_and_deriv.first );
171
152
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);
172
155
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) ;
174
157
}
175
158
176
159
template <int dim>
0 commit comments