1
// Copyright (C) 2005-2006 Anders Logg.
2
// Licensed under the GNU LGPL Version 2.1.
4
// First added: 2005-01-05
5
// Last changed: 2006-04-20
8
#include <dolfin/parameters.h>
9
#include <dolfin/TimeSlab.h>
10
#include <dolfin/TimeSlabSolver.h>
12
using namespace dolfin;
14
//-----------------------------------------------------------------------------
15
TimeSlabSolver::TimeSlabSolver(TimeSlab& timeslab)
16
: ode(timeslab.ode), method(*timeslab.method), tol(0.0), maxiter(0),
17
monitor(dolfin_get("ODE monitor convergence")),
18
num_timeslabs(0), num_global_iterations(0), num_local_iterations(0)
23
// Get maximum number of iterations
24
maxiter = dolfin_get("ODE maximum iterations");
26
//-----------------------------------------------------------------------------
27
TimeSlabSolver::~TimeSlabSolver()
29
if ( num_timeslabs > 0 )
31
const real n = static_cast<real>(num_timeslabs);
32
const real global_average = static_cast<real>(num_global_iterations) / n;
33
const real local_average = static_cast<real>(num_local_iterations) /
34
static_cast<real>(num_global_iterations);
35
message("Average number of global iterations per step: %.3f",
37
message("Average number of local iterations per global iteration: %.3f",
41
message("Total number of (macro) time steps: %d", num_timeslabs);
43
//-----------------------------------------------------------------------------
44
bool TimeSlabSolver::solve()
46
for (uint attempt = 0; attempt < maxiter; attempt++)
48
// Try to solve system
52
// Check if we should try again
59
//-----------------------------------------------------------------------------
60
bool TimeSlabSolver::solve(uint attempt)
66
for (uint iter = 0; iter < maxiter; iter++)
69
real d2 = iteration(tol, iter, d0, d1);
71
message("--- iter = %d: increment = %.3e", iter, d2);
78
num_global_iterations += iter + 1;
80
message("Time slab system of size %d converged in %d iterations.", size(), iter + 1);
85
// FIXME: implement better check and make this a parameter
86
if ( (iter > 0 && d2 > 1000.0 * d1) || !std::isnormal(d2) )
88
warning("Time slab system seems to be diverging.");
96
warning("Time slab system did not converge.");
99
//-----------------------------------------------------------------------------
100
bool TimeSlabSolver::retry()
102
// By default, we don't know how to make a new attempt
105
//-----------------------------------------------------------------------------
106
void TimeSlabSolver::start()
110
//-----------------------------------------------------------------------------
111
void TimeSlabSolver::end()
115
//-----------------------------------------------------------------------------
116
void TimeSlabSolver::chooseTolerance()
118
const real TOL = dolfin_get("ODE tolerance");
119
const real alpha = dolfin_get("ODE discrete tolerance factor");
121
tol = dolfin_get("ODE discrete tolerance");
122
if ( !dolfin_get("ODE fixed time step") )
123
tol = std::min(tol, alpha*TOL);
124
cout << "Using discrete tolerance tol = " << tol << "." << endl;
126
//-----------------------------------------------------------------------------