16 #ifndef dealii_solver_fire_h 17 #define dealii_solver_fire_h 20 #include <deal.II/base/config.h> 22 #include <deal.II/base/logstream.h> 24 #include <deal.II/lac/diagonal_matrix.h> 25 #include <deal.II/lac/solver.h> 30 DEAL_II_NAMESPACE_OPEN
90 template <
typename VectorType = Vector<
double>>
152 template <
typename PreconditionerType = DiagonalMatrix<VectorType>>
154 solve(
const std::function<
double(VectorType &,
const VectorType &)> &compute,
156 const PreconditionerType &inverse_mass_matrix);
163 template <
typename MatrixType,
typename PreconditionerType>
165 solve(
const MatrixType & A,
167 const VectorType & b,
168 const PreconditionerType &preconditioner);
181 const VectorType &g)
const;
195 template <
typename VectorType>
197 const double initial_timestep,
198 const double maximum_timestep,
199 const double maximum_linfty_norm)
200 : initial_timestep(initial_timestep)
201 , maximum_timestep(maximum_timestep)
202 , maximum_linfty_norm(maximum_linfty_norm)
204 AssertThrow(initial_timestep > 0. && maximum_timestep > 0. &&
205 maximum_linfty_norm > 0.,
206 ExcMessage(
"Expected positive values for initial_timestep, " 207 "maximum_timestep and maximum_linfty_norm but one " 208 "or more of the these values are not positive."));
213 template <
typename VectorType>
216 const AdditionalData & data)
217 :
SolverBase<VectorType>(solver_control, vector_memory)
218 , additional_data(data)
223 template <
typename VectorType>
225 const AdditionalData &data)
227 , additional_data(data)
232 template <
typename VectorType>
238 template <
typename VectorType>
239 template <
typename PreconditionerType>
242 const std::function<
double(VectorType &,
const VectorType &)> &compute,
244 const PreconditionerType &inverse_mass_matrix)
249 const double DELAYSTEP = 5;
250 const double TIMESTEP_GROW = 1.1;
251 const double TIMESTEP_SHRINK = 0.5;
252 const double ALPHA_0 = 0.1;
253 const double ALPHA_SHRINK = 0.99;
255 using real_type =
typename VectorType::real_type;
266 VectorType &velocities = *v;
267 VectorType &gradients = *g;
270 compute(gradients, x);
272 unsigned int iter = 0;
275 conv = this->iteration_status(iter, gradients * gradients, x);
280 const auto &maximum_timestep = additional_data.maximum_timestep;
281 double timestep = additional_data.initial_timestep;
284 double alpha = ALPHA_0;
286 unsigned int previous_iter_with_positive_v_dot_g = 0;
292 x.add(timestep, velocities);
293 inverse_mass_matrix.vmult(gradients, gradients);
294 velocities.add(-timestep, gradients);
297 compute(gradients, x);
299 const real_type gradient_norm_squared = gradients * gradients;
300 conv = this->iteration_status(iter, gradient_norm_squared, x);
305 const real_type v_dot_g = velocities * gradients;
309 const real_type velocities_norm_squared = velocities * velocities;
315 const real_type beta =
316 -alpha * std::sqrt(velocities_norm_squared / gradient_norm_squared);
319 velocities.sadd(1. - alpha, beta, gradients);
321 if (iter - previous_iter_with_positive_v_dot_g > DELAYSTEP)
324 timestep = std::min(timestep * TIMESTEP_GROW, maximum_timestep);
325 alpha *= ALPHA_SHRINK;
331 previous_iter_with_positive_v_dot_g = iter;
332 timestep *= TIMESTEP_SHRINK;
337 real_type vmax = velocities.linfty_norm();
342 const double minimal_timestep =
343 additional_data.maximum_linfty_norm / vmax;
344 if (minimal_timestep < timestep)
345 timestep = minimal_timestep;
348 print_vectors(iter, x, velocities, gradients);
360 template <
typename VectorType>
361 template <
typename MatrixType,
typename PreconditionerType>
365 const VectorType & b,
366 const PreconditionerType &preconditioner)
368 std::function<double(VectorType &, const VectorType &)> compute_func =
369 [&](VectorType &g,
const VectorType &x) ->
double {
378 return 0.5 * A.matrix_norm_square(x) - x *
b;
381 this->solve(compute_func, x, preconditioner);
386 template <
typename VectorType>
391 const VectorType &)
const 398 DEAL_II_NAMESPACE_CLOSE
virtual void print_vectors(const unsigned int, const VectorType &x, const VectorType &v, const VectorType &g) const
AdditionalData(const double initial_timestep=0.1, const double maximum_timestep=1, const double maximum_linfty_norm=1)
const AdditionalData additional_data
#define AssertThrow(cond, exc)
static ::ExceptionBase & ExcMessage(std::string arg1)
Stop iteration, goal reached.
const double maximum_timestep
#define Assert(cond, exc)
void solve(const std::function< double(VectorType &, const VectorType &)> &compute, VectorType &x, const PreconditionerType &inverse_mass_matrix)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
const double initial_timestep
const double maximum_linfty_norm
SolverFIRE(SolverControl &solver_control, VectorMemory< VectorType > &vector_memory, const AdditionalData &data=AdditionalData())
static ::ExceptionBase & ExcInternalError()