57
66
//-----------------------------------------------------------------------------
67
PointIntegralSolver::~PointIntegralSolver()
71
//-----------------------------------------------------------------------------
72
void PointIntegralSolver::reset_newton_solver()
74
_eta = parameters("newton_solver")["eta_0"];
76
for (unsigned int i=0; i < _recompute_jacobian.size(); i++)
77
_recompute_jacobian[i] = true;
79
//-----------------------------------------------------------------------------
80
void PointIntegralSolver::reset_stage_solutions()
82
// Iterate over stage forms
83
for (unsigned int stage=0; stage<_num_stages; stage++)
85
// Reset global stage solutions
86
*_scheme->stage_solutions()[stage]->vector() = 0.0;
88
// Reset local stage solutions
89
for (unsigned int row=0; row < _system_size; row++)
90
_local_stage_solutions[stage][row] = 0.0;
94
//-----------------------------------------------------------------------------
58
95
void PointIntegralSolver::step(double dt)
98
const bool reset_stage_solutions_ = parameters["reset_stage_solutions"];
99
const bool reset_newton_solver_ = parameters("newton_solver")["reset_each_step"];
101
// Check for reseting stage solutions
102
if (reset_stage_solutions_)
103
reset_stage_solutions();
105
// Check for reseting newtonsolver for each time step
106
if (reset_newton_solver_)
107
reset_newton_solver();
109
Timer t_step("PointIntegralSolver::step");
60
111
dolfin_assert(dt > 0.0);
62
Timer t_step_stage("Step: set the stage");
64
113
// Update time constant of scheme
65
114
*_scheme->dt() = dt;
67
116
// Time at start of timestep
68
117
const double t0 = *_scheme->t();
71
const Mesh& mesh = _scheme->stage_forms()[0][0]->mesh();
73
// Collect ref to dof map only need one as we require same trial and
74
// test space for all forms
75
const GenericDofMap& dofmap
76
= *_scheme->stage_forms()[0][0]->function_space(0)->dofmap();
78
// Get size of system (num dofs per vertex)
79
const unsigned int N = dofmap.num_entity_dofs(0);
80
const unsigned int dof_offset = mesh.type().num_entities(0);
81
const unsigned int num_stages = _scheme->stage_forms().size();
83
// Local solution vector at start of time step
85
Eigen::VectorXd u0(N);
87
// Local stage solutions
88
std::vector<Eigen::VectorXd >
89
local_stage_solutions(_scheme->stage_solutions().size());
90
for (unsigned int stage = 0; stage < num_stages; stage++)
91
local_stage_solutions[stage].resize(N);
93
// Update off-process coefficients
94
for (unsigned int i = 0; i < num_stages; i++)
96
for (unsigned int j = 0; j < _scheme->stage_forms()[i].size(); j++)
98
const std::vector<boost::shared_ptr<const GenericFunction> >
99
coefficients = _scheme->stage_forms()[i][j]->coefficients();
101
for (unsigned int k = 0; k < coefficients.size(); ++k)
102
coefficients[k]->update();
106
// Local to local dofs to be used in tabulate entity dofs
107
std::vector<std::size_t> local_to_local_dofs(N);
109
// Local to global dofs used when solution is fanned out to global vector
110
std::vector<dolfin::la_index> local_to_global_dofs(N);
119
// Get ownership range
120
const dolfin::la_index n0 = _dofmap.ownership_range().first;
121
const dolfin::la_index n1 = _dofmap.ownership_range().second;
112
123
// Iterate over vertices
113
//Progress p("Solving local point integral problems", mesh.num_vertices());
117
124
ufc::cell ufc_cell;
118
125
std::vector<double> vertex_coordinates;
119
for (std::size_t vert_ind = 0; vert_ind < mesh.num_vertices(); ++vert_ind)
126
for (std::size_t vert_ind=0; vert_ind < _mesh.num_vertices(); ++vert_ind)
121
Timer t_vert("Step: update vert");
123
129
// Cell containing vertex
124
const Cell cell(mesh, _vertex_map[vert_ind].first);
130
const Cell cell(_mesh, _vertex_map[vert_ind].first);
125
131
cell.get_vertex_coordinates(vertex_coordinates);
126
132
cell.get_cell_data(ufc_cell);
128
134
// Get all dofs for cell
129
135
// FIXME: Shold we include logics about empty dofmaps?
130
136
const std::vector<dolfin::la_index>& cell_dofs
131
= dofmap.cell_dofs(cell.index());
134
const unsigned int local_vert = _vertex_map[vert_ind].second;
137
= _dofmap.cell_dofs(cell.index());
136
139
// Tabulate local-local dofmap
137
dofmap.tabulate_entity_dofs(local_to_local_dofs, 0, local_vert);
139
// Fill local to global dof map
140
for (unsigned int row = 0; row < N; row++)
141
local_to_global_dofs[row] = cell_dofs[local_to_local_dofs[row]];
140
_dofmap.tabulate_entity_dofs(_local_to_local_dofs, 0,
141
_vertex_map[vert_ind].second);
143
// Fill local to global dof map and check that the dof is owned
144
bool owns_all_dofs = true;
145
for (unsigned int row=0; row < _system_size; row++)
147
_local_to_global_dofs[row] = cell_dofs[_local_to_local_dofs[row]];
148
if (_local_to_global_dofs[row] < n0 || n1 <=_local_to_global_dofs[row])
150
owns_all_dofs = false;
155
// If not owning all dofs
145
159
// Iterate over stage forms
146
for (unsigned int stage = 0; stage < num_stages; stage++)
160
for (unsigned int stage=0; stage<_num_stages; stage++)
149
*_scheme->t() = t0 + dt*_scheme->dt_stage_offset()[stage];
164
// TODO: Pass suitable bool vector here to avoid tabulating all coefficient dofs:
165
_ufcs[stage][0]->update(cell, vertex_coordinates, ufc_cell);
166
//some_integral.enabled_coefficients());
151
168
// Check if we have an explicit stage (only 1 form)
152
169
if (_ufcs[stage].size() == 1)
154
Timer t_expl("Explicit stage");
157
const ufc::point_integral& integral
158
= *_ufcs[stage][0]->default_point_integral;
160
// Update to current cell
161
Timer t_expl_update("Explicit stage: update_cell");
162
_ufcs[stage][0]->update(cell, vertex_coordinates, ufc_cell);
163
t_expl_update.stop();
165
// Tabulate cell tensor
166
Timer t_expl_tt("Explicit stage: tabulate_tensor");
167
integral.tabulate_tensor(_ufcs[stage][0]->A.data(),
168
_ufcs[stage][0]->w(),
169
vertex_coordinates.data(),
173
// Extract vertex dofs from tabulated tensor and put them into the local
174
// stage solution vector
175
// Extract vertex dofs from tabulated tensor
176
for (unsigned int row=0; row < N; row++)
178
local_stage_solutions[stage](row)
179
= _ufcs[stage][0]->A[local_to_local_dofs[row]];
182
// Put solution back into global stage solution vector
183
Timer t_expl_set("Explicit stage: set");
184
_scheme->stage_solutions()[stage]->vector()->set(
185
local_stage_solutions[stage].data(), N,
186
local_to_global_dofs.data());
171
_solve_explicit_stage(vert_ind, stage, ufc_cell, vertex_coordinates);
189
174
// or an implicit stage (2 forms)
192
Timer t_impl("Implicit stage");
194
const Parameters& newton_parameters = parameters("newton_solver");
197
Eigen::VectorXd& u = local_stage_solutions[stage];
199
unsigned int newton_iteration = 0;
200
bool newton_converged = false;
201
bool jacobian_retabulated = false;
202
const std::size_t maxiter = newton_parameters["maximum_iterations"];
203
const bool reuse_jacobian = newton_parameters["reuse_jacobian"];
204
const std::size_t iterations_to_retabulate_jacobian
205
= newton_parameters["iterations_to_retabulate_jacobian"];
206
const double relaxation = newton_parameters["relaxation_parameter"];
207
const std::string convergence_criterion
208
= newton_parameters["convergence_criterion"];
209
const double rtol = newton_parameters["relative_tolerance"];
210
const double atol = newton_parameters["absolute_tolerance"];
211
const bool report = newton_parameters["report"];
212
//const int num_threads = 0;
214
/// Most recent residual and intitial residual
215
double residual = 1.0;
216
double residual0 = 1.0;
217
double relative_residual = 1.0;
219
//const double relaxation = 1.0;
221
// Initialize la structures
222
Eigen::VectorXd F(N), dx(N);
224
// Get point integrals
225
const ufc::point_integral& F_integral
226
= *_ufcs[stage][0]->default_point_integral;
227
const ufc::point_integral& J_integral
228
= *_ufcs[stage][1]->default_point_integral;
230
// Update to current cell. This only need to be done once for
231
// each stage and vertex
232
Timer t_impl_update("Implicit stage: update_cell");
233
_ufcs[stage][0]->update(cell, vertex_coordinates, ufc_cell);
234
_ufcs[stage][1]->update(cell, vertex_coordinates, ufc_cell);
235
t_impl_update.stop();
237
// Tabulate an initial residual solution
238
Timer t_impl_tt_F("Implicit stage: tabulate_tensor (F)");
239
F_integral.tabulate_tensor(_ufcs[stage][0]->A.data(),
240
_ufcs[stage][0]->w(),
241
vertex_coordinates.data(),
245
// Extract vertex dofs from tabulated tensor, together with
246
// the old stage solution
247
Timer t_impl_update_F("Implicit stage: update_F");
248
for (unsigned int row = 0; row < N; row++)
250
F(row) = _ufcs[stage][0]->A[local_to_local_dofs[row]];
252
// Grab old value of stage solution as an initial start
253
// value. This value was also used to tabulate the initial
254
// value of the F_integral above and we therefore just grab
255
// it from the restricted coeffcients
256
u(row) = _ufcs[stage][0]->w()[_coefficient_index[stage][0]][local_to_local_dofs[row]];
258
t_impl_update_F.stop();
261
while (!newton_converged && newton_iteration < maxiter)
263
if (_retabulate_J || !reuse_jacobian)
266
Timer t_impl_tt_J("Implicit stage: tabulate_tensor (J)");
267
J_integral.tabulate_tensor(_ufcs[stage][1]->A.data(),
268
_ufcs[stage][1]->w(),
269
vertex_coordinates.data(),
273
// Extract vertex dofs from tabulated tensor
274
Timer t_impl_update_J("Implicit stage: update_J");
275
for (unsigned int row = 0; row < N; row++)
277
for (unsigned int col=0; col < N; col++)
280
= _ufcs[stage][1]->A[local_to_local_dofs[row]*dof_offset*N
281
+ local_to_local_dofs[col]];
284
t_impl_update_J.stop();
286
// LU factorize Jacobian
287
Timer lu_factorize("Implicit stage: LU factorize");
289
_retabulate_J = false;
292
// Perform linear solve By forward backward substitution
293
Timer forward_backward_substitution("Implicit stage: fb substitution");
296
forward_backward_substitution.stop();
299
if (convergence_criterion == "residual")
301
else if (convergence_criterion == "incremental")
302
residual = dx.norm();
304
error("Unknown Newton convergence criterion");
306
// If initial residual
307
if (newton_iteration == 0)
308
residual0 = residual;
311
relative_residual = residual / residual0;
314
if (std::abs(1.0 - relaxation) < DOLFIN_EPS)
319
// Update number of iterations
322
// Put solution back into restricted coefficients before
323
// tabulate new residual
324
for (unsigned int row = 0; row < N; row++)
326
_ufcs[stage][0]->w()[_coefficient_index[stage][0]][local_to_local_dofs[row]]
329
// Tabulate new residual
331
F_integral.tabulate_tensor(_ufcs[stage][0]->A.data(),
332
_ufcs[stage][0]->w(),
333
vertex_coordinates.data(),
337
t_impl_update_F.start();
338
// Extract vertex dofs from tabulated tensor
339
for (unsigned int row = 0; row < N; row++)
340
F(row) = _ufcs[stage][0]->A[local_to_local_dofs[row]];
341
t_impl_update_F.stop();
343
// Output iteration number and residual (only first vertex)
344
if (report && (newton_iteration > 0) && (vert_ind == 0))
346
info("Point solver newton iteration %d: r (abs) = %.3e (tol = %.3e) "\
347
"r (rel) = %.3e (tol = %.3e)",
348
newton_iteration, residual, atol, relative_residual, rtol);
351
// Check for retabulation of Jacobian
353
&& newton_iteration > iterations_to_retabulate_jacobian
354
&& !jacobian_retabulated)
356
jacobian_retabulated = true;
357
_retabulate_J = true;
360
info("Retabulating Jacobian.");
362
// If there is a solution coefficient in the jacobian form
363
if (_coefficient_index[stage].size()==2)
365
// Put solution back into restricted coefficients before
366
// tabulate new jacobian
367
for (unsigned int row=0; row < N; row++)
368
_ufcs[stage][1]->w()[_coefficient_index[stage][1]][local_to_local_dofs[row]] = u(row);
373
// Return true if convergence criterion is met
374
if (relative_residual < rtol || residual < atol)
375
newton_converged = true;
378
if (newton_converged)
380
Timer t_impl_set("Implicit stage: set");
381
// Put solution back into global stage solution vector
382
_scheme->stage_solutions()[stage]->vector()->set(u.data(), u.size(),
383
&local_to_global_dofs[0]);
387
info("Last iteration before error %d: r (abs) = %.3e (tol = %.3e) "
388
"r (rel) = %.3e (tol = %.3e)", newton_iteration, residual, atol,
389
relative_residual, rtol);
390
error("Newton solver in PointIntegralSolver did not converge.");
177
_solve_implicit_stage(vert_ind, stage, cell, ufc_cell, vertex_coordinates);
395
Timer t_vert_axpy("Step: AXPY solution");
397
// Get local u0 solution and add the stage derivatives
398
_scheme->solution()->vector()->get_local(u0.data(), u0.size(),
399
&local_to_global_dofs[0]);
401
// Do the last stage and put back into solution vector
402
FunctionAXPY last_stage = _scheme->last_stage()*dt;
404
// Axpy local solution vectors
405
for (unsigned int stage=0; stage < num_stages; stage++)
406
u0 += last_stage.pairs()[stage].first*local_stage_solutions[stage];
182
Timer t_last_stage("Last stage: tabulate_tensor");
184
// Last stage point integral
185
const ufc::point_integral& integral = *_last_stage_ufc->default_point_integral;
187
// Update coeffcients for last stage
188
// TODO: Pass suitable bool vector here to avoid tabulating all coefficient dofs:
189
_last_stage_ufc->update(cell, vertex_coordinates, ufc_cell);
190
//integral.enabled_coefficients());
192
// Tabulate cell tensor
193
integral.tabulate_tensor(_last_stage_ufc->A.data(), _last_stage_ufc->w(),
194
vertex_coordinates.data(),
195
_vertex_map[vert_ind].second,
196
ufc_cell.orientation);
198
// Update solution with a tabulation of the last stage
199
for (unsigned int row=0; row < _system_size; row++)
200
_y[row] = _last_stage_ufc->A[_local_to_local_dofs[row]];
408
202
// Update global solution with last stage
409
_scheme->solution()->vector()->set(u0.data(), local_to_global_dofs.size(),
410
&local_to_global_dofs[0]);
203
_scheme->solution()->vector()->set(_y.data(), _local_to_global_dofs.size(),
204
_local_to_global_dofs.data());
207
for (unsigned int stage=0; stage<_num_stages; stage++)
208
_scheme->stage_solutions()[stage]->vector()->apply("insert");
210
_scheme->solution()->vector()->apply("insert");
416
213
*_scheme->t() = t0 + dt;
216
//-----------------------------------------------------------------------------
217
void PointIntegralSolver::_solve_explicit_stage(std::size_t vert_ind,
219
const ufc::cell& ufc_cell,
220
const std::vector<double>& vertex_coordinates)
222
Timer t_expl("Explicit stage");
225
const unsigned int local_vert = _vertex_map[vert_ind].second;
228
const ufc::point_integral& integral = *_ufcs[stage][0]->default_point_integral;
230
// Tabulate cell tensor
231
Timer t_expl_tt("Explicit stage: tabulate_tensor");
232
integral.tabulate_tensor(_ufcs[stage][0]->A.data(), _ufcs[stage][0]->w(),
233
vertex_coordinates.data(), local_vert,
234
ufc_cell.orientation);
237
// Extract vertex dofs from tabulated tensor and put them into the local
238
// stage solution vector
239
// Extract vertex dofs from tabulated tensor
240
for (unsigned int row=0; row < _system_size; row++)
242
_local_stage_solutions[stage][row] = _ufcs[stage][0]->A[_local_to_local_dofs[row]];
245
// Put solution back into global stage solution vector
246
// NOTE: This so an UFC.update (coefficient restriction) would just work
247
_scheme->stage_solutions()[stage]->vector()->set(
248
_local_stage_solutions[stage].data(), _system_size,
249
_local_to_global_dofs.data());
252
//-----------------------------------------------------------------------------
253
void PointIntegralSolver::_solve_implicit_stage(std::size_t vert_ind,
254
unsigned int stage, const Cell& cell,
255
const ufc::cell& ufc_cell,
256
const std::vector<double>& vertex_coordinates)
259
Timer t_impl("Implicit stage");
261
// Do a simplified newton solve
262
_simplified_newton_solve(vert_ind, stage, cell, ufc_cell, vertex_coordinates);
264
// Put solution back into global stage solution vector
265
_scheme->stage_solutions()[stage]->vector()->set(_local_stage_solutions[stage].data(), \
267
_local_to_global_dofs.data());
418
270
//-----------------------------------------------------------------------------
419
271
void PointIntegralSolver::step_interval(double t0, double t1, double dt)
450
302
//-----------------------------------------------------------------------------
303
void PointIntegralSolver::_compute_jacobian(std::vector<double>& jac,
304
const std::vector<double>& u,
305
unsigned int local_vert,
306
UFC& loc_ufc, const Cell& cell,
307
const ufc::cell& ufc_cell,
308
int coefficient_index,
309
const std::vector<double>& vertex_coordinates)
311
const ufc::point_integral& J_integral = *loc_ufc.default_point_integral;
313
//Timer _timer_compute_jac("Implicit stage: Compute jacobian");
314
//Timer t_impl_update("Update_cell");
315
// TODO: Pass suitable bool vector here to avoid tabulating all coefficient dofs:
316
loc_ufc.update(cell, vertex_coordinates, ufc_cell);
317
//J_integral.enabled_coefficients());
318
//t_impl_update.stop();
320
// If there is a solution coefficient in the jacobian form
321
if (coefficient_index>0)
323
// Put solution back into restricted coefficients before tabulate new jacobian
324
for (unsigned int row=0; row < _system_size; row++)
326
loc_ufc.w()[coefficient_index][_local_to_local_dofs[row]] = u[row];
331
Timer t_impl_tt_jac("Implicit stage: tabulate_tensor (J)");
332
J_integral.tabulate_tensor(loc_ufc.A.data(), loc_ufc.w(),
333
vertex_coordinates.data(),
335
ufc_cell.orientation);
336
t_impl_tt_jac.stop();
338
// Extract vertex dofs from tabulated tensor
339
//Timer t_impl_update_jac("Implicit stage: update_jac");
340
for (unsigned int row=0; row < _system_size; row++)
341
for (unsigned int col=0; col < _system_size; col++)
342
jac[row*_system_size + col] = loc_ufc.A[_local_to_local_dofs[row]*
343
_dof_offset*_system_size +
344
_local_to_local_dofs[col]];
345
//t_impl_update_jac.stop();
347
// LU factorize Jacobian
348
//Timer lu_factorize("Implicit stage: LU factorize");
350
_num_jacobian_computations += 1;
352
//-----------------------------------------------------------------------------
353
void PointIntegralSolver::_lu_factorize(std::vector<double>& A)
358
const int system_size = _system_size;
360
for (int k = 1; k < system_size; k++)
363
for (int i = 0; i <= k-1; ++i)
367
for (int r = 0; r <= i-1; r++)
369
sum += A[i*_system_size+r]*A[r*_system_size+k];
372
A[i*_system_size+k] -=sum;
375
for (int r = 0; r <= i-1; r++)
377
sum += A[k*_system_size+r]*A[r*_system_size+i];
380
A[k*_system_size+i] = (A[k*_system_size+i]-sum)/A[i*_system_size+i];
385
for (int r = 0; r <= k-1; r++)
387
sum += A[k*_system_size+r]*A[r*_system_size+k];
390
A[k*_system_size+k] -= sum;
394
//-----------------------------------------------------------------------------
395
void PointIntegralSolver::_forward_backward_subst(const std::vector<double>& A,
396
const std::vector<double>& b,
397
std::vector<double>& x) const
399
// solves Ax = b with forward backward substitution, provided that
400
// A is already LU factorized
407
for (unsigned int i=1; i < _system_size; ++i)
410
for (unsigned int j=0; j <= i-1; ++j)
412
sum = sum + A[i*_system_size+j]*x[j];
418
const unsigned int _system_size_m_1 = _system_size-1;
419
x[_system_size_m_1] = x[_system_size_m_1]/\
420
A[_system_size_m_1*_system_size+_system_size_m_1];
423
for (int i = _system_size-2; i >= 0; i--)
426
for (unsigned int j=i+1; j < _system_size; ++j)
428
sum = sum +A[i*_system_size+j]*x[j];
431
x[i] = (x[i]-sum)/A[i*_system_size+i];
434
//-----------------------------------------------------------------------------
435
double PointIntegralSolver::_norm(const std::vector<double>& vec) const
439
for (unsigned int i = 0; i < vec.size(); ++i)
440
l2_norm += vec[i]*vec[i];
442
l2_norm = std::sqrt(l2_norm);
445
//-----------------------------------------------------------------------------
451
446
void PointIntegralSolver::_check_forms()
453
448
// Iterate over stage forms and check they include point integrals
454
std::vector<std::vector<boost::shared_ptr<const Form> > >& stage_forms
449
std::vector<std::vector<std::shared_ptr<const Form> > >& stage_forms
455
450
= _scheme->stage_forms();
456
451
for (unsigned int i=0; i < stage_forms.size(); i++)
584
602
//-----------------------------------------------------------------------------
603
void PointIntegralSolver::_simplified_newton_solve(
604
std::size_t vert_ind, unsigned int stage,
606
// int coefficient_index_F, int coefficient_index_J,
608
const ufc::cell& ufc_cell,
609
const std::vector<double>& vertex_coordinates)
612
//Timer _timer_newton_solve("Implicit stage: Newton solve");
613
const Parameters& newton_solver_params = parameters("newton_solver");
614
const size_t report_vertex = newton_solver_params["report_vertex"];
615
const double kappa = newton_solver_params["kappa"];
616
const double rtol = newton_solver_params["relative_tolerance"];
617
std::size_t max_iterations = newton_solver_params["maximum_iterations"];
618
const double max_relative_previous_residual = newton_solver_params["max_relative_previous_residual"];
619
const double relaxation = newton_solver_params["relaxation_parameter"];
620
const bool report = newton_solver_params["report"];
621
const bool verbose_report = newton_solver_params["verbose_report"];
622
bool always_recompute_jacobian = newton_solver_params["always_recompute_jacobian"];
623
const unsigned int local_vert = _vertex_map[vert_ind].second;
624
UFC& loc_ufc_F = *_ufcs[stage][0];
625
UFC& loc_ufc_J = *_ufcs[stage][1];
626
const int coefficient_index_F = _coefficient_index[stage][0];
627
const int coefficient_index_J = _coefficient_index[stage].size()==2 ?
628
_coefficient_index[stage][1] : -1;
629
const unsigned int jac_index = _scheme->jacobian_index(stage);
630
std::vector<double>& jac = _jacobians[jac_index];
632
if (newton_solver_params["recompute_jacobian_each_solve"])
633
_recompute_jacobian[jac_index] = true;
635
bool newton_solve_restared = false;
636
unsigned int newton_iterations = 0;
637
double relative_previous_residual = 1.0, residual, prev_residual = 1.0,
638
initial_residual = 1.0, relative_residual = 1.0;
640
// Get point integrals
641
const ufc::point_integral& F_integral = *loc_ufc_F.default_point_integral;
644
std::vector<double>& u = _local_stage_solutions[stage];
646
// Update with previous local solution and make a backup of solution to
647
// be used in a potential restarting of newton solver
648
for (unsigned int row=0; row < _system_size; row++)
649
_u0[row] = u[row] = loc_ufc_F.w()[coefficient_index_F][_local_to_local_dofs[row]];
655
Timer t_impl_tt_F("Implicit stage: tabulate_tensor (F)");
656
F_integral.tabulate_tensor(loc_ufc_F.A.data(), loc_ufc_F.w(),
657
vertex_coordinates.data(),
659
ufc_cell.orientation);
662
// Extract vertex dofs from tabulated tensor, together with the old stage
664
for (unsigned int row=0; row < _system_size; row++)
665
_residual[row] = loc_ufc_F.A[_local_to_local_dofs[row]];
667
residual = _norm(_residual);
668
if (newton_iterations == 0)
669
initial_residual = residual;//std::max(residual, DOLFIN_EPS);
671
relative_residual = residual/initial_residual;
673
// Check for relative residual convergence
674
if (relative_residual < rtol)
677
// Should we recompute jacobian
678
if (_recompute_jacobian[jac_index] || always_recompute_jacobian)
680
_compute_jacobian(jac, u, local_vert, loc_ufc_J, cell, ufc_cell,
681
coefficient_index_J, vertex_coordinates);
682
_recompute_jacobian[jac_index] = false;
685
// Perform linear solve By forward backward substitution
686
//Timer forward_backward_substitution("Implicit stage: fb substituion");
687
_forward_backward_subst(jac, _residual, _dx);
688
//forward_backward_substitution.stop();
690
// Newton_Iterations == 0
691
if (newton_iterations == 0)
693
// On first iteration we need an approximation of eta. We take
694
// the one from previous step and increase it slightly. This is
695
// important for linear problems which only should recquire 1
696
// iteration to converge.
697
_eta = _eta > DOLFIN_EPS ? _eta : DOLFIN_EPS;
698
_eta = std::pow(_eta, 0.8);
705
// How fast are we converging?
706
relative_previous_residual = residual/prev_residual;
708
if (always_recompute_jacobian)
711
if ((report && vert_ind == report_vertex) || verbose_report)
712
info("Newton solver after %d iterations. vertex: %d, " \
713
"relative_previous_residual: %.3f, " \
714
"relative_residual: %.3e, residual: %.3e.",
715
newton_iterations, vert_ind, relative_previous_residual,
716
relative_residual, residual);
721
else if (relative_previous_residual > 1)
724
if ((report && vert_ind == report_vertex) || verbose_report)
725
info("Newton solver diverges after %d iterations. vertex: %d, " \
726
"relative_previous_residual: %.3f, " \
727
"relative_residual: %.3e, residual: %.3e.",
728
newton_iterations, vert_ind, relative_previous_residual,
729
relative_residual, residual);
731
// If we have not restarted newton solve previously
732
if (!newton_solve_restared)
734
if ((report && vert_ind == report_vertex) || verbose_report)
735
info("Restarting newton solve for vertex: %d", vert_ind);
738
newton_solve_restared = true;
739
always_recompute_jacobian = true;
742
for (unsigned int row=0; row < _system_size; row++)
743
loc_ufc_F.w()[coefficient_index_F][_local_to_local_dofs[row]] = u[row] = _u0[row];
746
_eta = parameters("newton_solver")["eta_0"];
747
newton_iterations = 0;
748
relative_previous_residual = prev_residual = initial_residual = relative_residual = 1.0;
749
max_iterations = 400;
755
// We converge too slow
756
else if (relative_previous_residual >= max_relative_previous_residual ||
757
residual > (kappa*rtol*(1 - relative_previous_residual)/ \
758
std::pow(relative_previous_residual, \
759
max_iterations - newton_iterations)))
762
if ((report && vert_ind == report_vertex) || verbose_report)
763
info("Newton solver converges too slow at iteration %d. vertex: %d, " \
764
"relative_previous_residual: %.3f, " \
765
"relative_residual: %.3e, residual: %.3e. Recomputing jacobian.",
766
newton_iterations, vert_ind, relative_previous_residual,
767
relative_residual, residual);
769
_recompute_jacobian[jac_index] = true;
774
if ((report && vert_ind == report_vertex) || verbose_report)
775
info("Newton solver after %d iterations. vertex: %d, " \
776
"relative_previous_residual: %.3f, " \
777
"relative_residual: %.3e, residual: %.3e.",
778
newton_iterations, vert_ind, relative_previous_residual,
779
relative_residual, residual);
782
_eta = relative_previous_residual/(1.0 - relative_previous_residual);
789
if (newton_iterations > max_iterations)
792
info("Newton solver did not converge after %d iterations. vertex: %d, " \
793
"relative_previous_residual: %.3f, " \
794
"relative_residual: %.3e, residual: %.3e.", max_iterations, vert_ind,
795
relative_previous_residual, relative_residual, residual);
797
error("Newton solver in PointIntegralSolver exeeded maximal iterations.");
801
if (std::abs(1.0 - relaxation) < DOLFIN_EPS)
802
for (unsigned int i=0; i < u.size(); i++)
805
for (unsigned int i=0; i < u.size(); i++)
806
u[i] -= relaxation*_dx[i];
808
// Put solution back into restricted coefficients before tabulate new residual
809
for (unsigned int row=0; row < _system_size; row++)
810
loc_ufc_F.w()[coefficient_index_F][_local_to_local_dofs[row]] = u[row];
812
prev_residual = residual;
815
} while(_eta*relative_residual >= kappa*rtol);
817
if ((report && vert_ind == report_vertex) || verbose_report)
818
info("Newton solver converged after %d iterations. vertex: %d, "\
819
"relative_previous_residual: %.3f, relative_residual: %.3e, "\
820
"residual: %.3e.", newton_iterations, vert_ind,
821
relative_previous_residual, relative_residual, residual);
824
//-----------------------------------------------------------------------------