DUNE PDELab (2.7)

newton.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3
4//
5// Note: This Newton is deprecated and will be removed for PDELab 2.8. Please
6// use the Newton from <dune/pdelab/solver/newton.hh>
7//
8#ifndef DUNE_PDELAB_NEWTON_NEWTON_HH
9#define DUNE_PDELAB_NEWTON_NEWTON_HH
10
11#include <iostream>
12#include <iomanip>
13#include <cmath>
14#include <memory>
15
16#include <type_traits>
17
18#include <math.h>
19
23#include <dune/common/timer.hh>
25
26#include <dune/pdelab/backend/solver.hh>
27#include <dune/pdelab/constraints/common/constraints.hh>
28#include <dune/pdelab/solver/newton.hh>
29
30
31// Note: Before introducing the new Newton there was no doxygen documentation
32// for Newton at all. This means that it doesn't make any sense to have doxygen
33// documentation for the old Newton now.
34#ifndef DOXYGEN
35
36namespace Dune
37{
38 namespace PDELab
39 {
40
41 class NewtonLineSearchError : public NewtonError {};
42 class NewtonNotConverged : public NewtonError {};
43
44 // Status information of Newton's method
45 template<class RFType>
46 struct NewtonResult : LinearSolverResult<RFType>
47 {
48 RFType first_defect; // the first defect
49 RFType defect; // the final defect
50 double assembler_time; // Cumulative time for matrix assembly
51 double linear_solver_time; // Cumulative time for linear solver
52 int linear_solver_iterations; // Total number of linear iterations
53
54 NewtonResult() :
55 first_defect(0.0), defect(0.0), assembler_time(0.0), linear_solver_time(0.0),
56 linear_solver_iterations(0) {}
57 };
58
59 template<class GOS, class TrlV, class TstV>
60 class NewtonBase
61 {
62 typedef GOS GridOperator;
63 typedef TrlV TrialVector;
64 typedef TstV TestVector;
65
66 typedef typename TestVector::ElementType RFType;
67 typedef typename GOS::Traits::Jacobian Matrix;
68
69
70 public:
71 // export result type
72 typedef NewtonResult<RFType> Result;
73
74 void setVerbosityLevel(unsigned int verbosity_level)
75 {
76 if (gridoperator_.trialGridFunctionSpace().gridView().comm().rank()>0)
77 verbosity_level_ = 0;
78 else
79 verbosity_level_ = verbosity_level;
80 }
81
83 void setKeepMatrix(bool b)
84 {
85 keep_matrix_ = b;
86 }
87
89 bool keepMatrix() const
90 {
91 return keep_matrix_;
92 }
93
95 void discardMatrix()
96 {
97 if(A_)
98 A_.reset();
99 }
100
101 protected:
102 const GridOperator& gridoperator_;
103 TrialVector *u_;
104 std::shared_ptr<TrialVector> z_;
105 std::shared_ptr<TestVector> r_;
106 std::shared_ptr<Matrix> A_;
107 Result res_;
108 unsigned int verbosity_level_;
109 RFType prev_defect_;
110 RFType linear_reduction_;
111 bool reassembled_;
112 RFType reduction_;
113 RFType abs_limit_;
114 bool keep_matrix_;
115
116 NewtonBase(const GridOperator& go, TrialVector& u)
117 : gridoperator_(go)
118 , u_(&u)
119 , verbosity_level_(1)
120 , keep_matrix_(true)
121 {
122 if (gridoperator_.trialGridFunctionSpace().gridView().comm().rank()>0)
123 verbosity_level_ = 0;
124 }
125
126 NewtonBase(const GridOperator& go)
127 : gridoperator_(go)
128 , u_(0)
129 , verbosity_level_(1)
130 , keep_matrix_(true)
131 {
132 if (gridoperator_.trialGridFunctionSpace().gridView().comm().rank()>0)
133 verbosity_level_ = 0;
134 }
135
136 virtual ~NewtonBase() { }
137
138 virtual bool terminate() = 0;
139 virtual void prepare_step(Matrix& A, TestVector& r) = 0;
140 virtual void line_search(TrialVector& z, TestVector& r) = 0;
141 virtual void defect(TestVector& r) = 0;
142 }; // end class NewtonBase
143
144 template<class GOS, class S, class TrlV, class TstV>
145 class NewtonSolver : public virtual NewtonBase<GOS,TrlV,TstV>
146 {
147 typedef S Solver;
148 typedef GOS GridOperator;
149 typedef TrlV TrialVector;
150 typedef TstV TestVector;
151
152 typedef typename TestVector::ElementType RFType;
153 typedef typename GOS::Traits::Jacobian Matrix;
154
155 public:
156 typedef NewtonResult<RFType> Result;
157
158 NewtonSolver(const GridOperator& go, TrialVector& u_, Solver& solver)
159 : NewtonBase<GOS,TrlV,TstV>(go,u_)
160 , solver_(solver)
161 , result_valid_(false)
162 , use_maxnorm_(false)
163 {}
164
165 NewtonSolver(const GridOperator& go, Solver& solver)
166 : NewtonBase<GOS,TrlV,TstV>(go)
167 , solver_(solver)
168 , result_valid_(false)
169 , use_maxnorm_(false)
170 , hanging_node_modifications_(false)
171 {}
172
173 void apply();
174
175 void apply(TrialVector& u_);
176
177 const Result& result() const
178 {
179 if (!result_valid_)
180 DUNE_THROW(NewtonError,
181 "NewtonSolver::result() called before NewtonSolver::solve()");
182 return this->res_;
183 }
184
186 void setUseMaxNorm(bool b)
187 {
188 use_maxnorm_ = b;
189 }
190
191 void setHangingNodeModifications(bool b)
192 {
193 hanging_node_modifications_ = b;
194 }
195
196 protected:
197 virtual void defect(TestVector& r) override
198 {
199 if (hanging_node_modifications_){
200 auto dirichletValues = *this->u_;
201 // Set all non dirichlet values to zero
202 Dune::PDELab::set_shifted_dofs(this->gridoperator_.localAssembler().trialConstraints(), 0.0, dirichletValues);
203 // Set all constrained DOFs to zero in solution
204 Dune::PDELab::set_constrained_dofs(this->gridoperator_.localAssembler().trialConstraints(), 0.0, *this->u_);
205 // Copy correct Dirichlet values back into solution vector
206 Dune::PDELab::copy_constrained_dofs(this->gridoperator_.localAssembler().trialConstraints(), dirichletValues, *this->u_);
207 // Interpolate periodic constraints / hanging nodes
208 this->gridoperator_.localAssembler().backtransform(*this->u_);
209 }
210
211 r = 0.0;
212 this->gridoperator_.residual(*this->u_, r);
213 // use maximum norm as a stopping criterion, this helps loosen the tolerance
214 // when solving for stationary solutions of nonlinear time-dependent problems
215 // the default is to use the Euclidean norm (in the else-block) as before
216 if(use_maxnorm_)
217 {
218 auto rank_max = Backend::native(r).infinity_norm();
219 this->res_.defect = this->gridoperator_.testGridFunctionSpace().gridView().comm().max(rank_max);
220 }
221 else
222 {
223 this->res_.defect = this->solver_.norm(r);
224 }
225 if (!std::isfinite(this->res_.defect))
226 DUNE_THROW(NewtonDefectError,
227 "NewtonSolver::defect(): Non-linear defect is NaN or Inf");
228 }
229
230
231 private:
232 void linearSolve(Matrix& A, TrialVector& z, TestVector& r) const
233 {
234 if (this->verbosity_level_ >= 4)
235 std::cout << " Solving linear system..." << std::endl;
236 z = 0.0;
237 // If possible tell solver backend to reuse linear system when we did not reassemble.
238 Impl::setLinearSystemReuse(this->solver_, !this->reassembled_);
239 this->solver_.apply(A, z, r, this->linear_reduction_);
240
241 ios_base_all_saver restorer(std::cout); // store old ios flags
242
243 if (!this->solver_.result().converged)
244 DUNE_THROW(NewtonLinearSolverError,
245 "NewtonSolver::linearSolve(): Linear solver did not converge "
246 "in " << this->solver_.result().iterations << " iterations");
247 if (this->verbosity_level_ >= 4)
248 std::cout << " linear solver iterations: "
249 << std::setw(12) << solver_.result().iterations << std::endl
250 << " linear defect reduction: "
251 << std::setw(12) << std::setprecision(4) << std::scientific
252 << solver_.result().reduction << std::endl;
253 }
254
255 Solver& solver_;
256 bool result_valid_;
257 bool use_maxnorm_;
258 bool hanging_node_modifications_;
259 }; // end class NewtonSolver
260
261 template<class GOS, class S, class TrlV, class TstV>
262 void NewtonSolver<GOS,S,TrlV,TstV>::apply(TrialVector& u)
263 {
264 this->u_ = &u;
265 apply();
266 }
267
268 template<class GOS, class S, class TrlV, class TstV>
270 {
271 this->res_.iterations = 0;
272 this->res_.converged = false;
273 this->res_.reduction = 1.0;
274 this->res_.conv_rate = 1.0;
275 this->res_.elapsed = 0.0;
276 this->res_.assembler_time = 0.0;
277 this->res_.linear_solver_time = 0.0;
278 this->res_.linear_solver_iterations = 0;
279 result_valid_ = true;
280 Timer timer;
281
282 try
283 {
284 if(!this->r_) {
285 // std::cout << "=== Setting up residual vector ..." << std::endl;
286 this->r_ = std::make_shared<TestVector>(this->gridoperator_.testGridFunctionSpace());
287 }
288 // residual calculation in member function "defect":
289 //--------------------------------------------------
290 // - set residual vector to zero
291 // - calculate new residual
292 // - store norm of residual in "this->res_.defect"
293 this->defect(*this->r_);
294 this->res_.first_defect = this->res_.defect;
295 this->prev_defect_ = this->res_.defect;
296
297 if (this->verbosity_level_ >= 2)
298 {
299 // store old ios flags
300 ios_base_all_saver restorer(std::cout);
301 std::cout << " Initial defect: "
302 << std::setw(12) << std::setprecision(4) << std::scientific
303 << this->res_.defect << std::endl;
304 }
305
306 if(!this->A_) {
307 // std::cout << "==== Setting up jacobian matrix ... " << std::endl;
308 this->A_ = std::make_shared<Matrix>(this->gridoperator_);
309 }
310 if(!this->z_) {
311 // std::cout << "==== Setting up correction vector ... " << std::endl;
312 this->z_ = std::make_shared<TrialVector>(this->gridoperator_.trialGridFunctionSpace());
313 }
314
315 while (!this->terminate())
316 {
317 if (this->verbosity_level_ >= 3)
318 std::cout << " Newton iteration " << this->res_.iterations
319 << " --------------------------------" << std::endl;
320
321 Timer assembler_timer;
322 try
323 {
324 // jacobian calculation in member function "prepare_step"
325 //-------------------------------------------------------
326 // - if above reassemble threshold
327 // - set jacobian to zero
328 // - calculate new jacobian
329 // - set linear reduction
330 this->prepare_step(*this->A_,*this->r_);
331 }
332 catch (...)
333 {
334 this->res_.assembler_time += assembler_timer.elapsed();
335 throw;
336 }
337 double assembler_time = assembler_timer.elapsed();
338 this->res_.assembler_time += assembler_time;
339 if (this->verbosity_level_ >= 3)
340 std::cout << " matrix assembly time: "
341 << std::setw(12) << std::setprecision(4) << std::scientific
342 << assembler_time << std::endl;
343
344 Timer linear_solver_timer;
345 try
346 {
347 // solution of linear system in member function "linearSolve"
348 //-----------------------------------------------------------
349 // - set initial guess for correction z to zero
350 // - call linear solver
351 this->linearSolve(*this->A_, *this->z_, *this->r_);
352 }
353 catch (...)
354 {
355 this->res_.linear_solver_time += linear_solver_timer.elapsed();
356 this->res_.linear_solver_iterations += this->solver_.result().iterations;
357 throw;
358 }
359 double linear_solver_time = linear_solver_timer.elapsed();
360 this->res_.linear_solver_time += linear_solver_time;
361 this->res_.linear_solver_iterations += this->solver_.result().iterations;
362
363 try
364 {
365 // line search with correction z
366 // the undamped version is also integrated in here
367 this->line_search(*this->z_, *this->r_);
368 }
369 catch (NewtonLineSearchError&)
370 {
371 if (this->reassembled_)
372 throw;
373 if (this->verbosity_level_ >= 3)
374 std::cout << " line search failed - trying again with reassembled matrix" << std::endl;
375 continue;
376 }
377
378 this->res_.reduction = this->res_.defect/this->res_.first_defect;
379 this->res_.iterations++;
380 this->res_.conv_rate = std::pow(this->res_.reduction, 1.0/this->res_.iterations);
381
382 // store old ios flags
383 ios_base_all_saver restorer(std::cout);
384
385 if (this->verbosity_level_ >= 3)
386 std::cout << " linear solver time: "
387 << std::setw(12) << std::setprecision(4) << std::scientific
388 << linear_solver_time << std::endl
389 << " defect reduction (this iteration):"
390 << std::setw(12) << std::setprecision(4) << std::scientific
391 << this->res_.defect/this->prev_defect_ << std::endl
392 << " defect reduction (total): "
393 << std::setw(12) << std::setprecision(4) << std::scientific
394 << this->res_.reduction << std::endl
395 << " new defect: "
396 << std::setw(12) << std::setprecision(4) << std::scientific
397 << this->res_.defect << std::endl;
398 if (this->verbosity_level_ == 2)
399 std::cout << " Newton iteration " << std::setw(2) << this->res_.iterations
400 << ". New defect: "
401 << std::setw(12) << std::setprecision(4) << std::scientific
402 << this->res_.defect
403 << ". Reduction (this): "
404 << std::setw(12) << std::setprecision(4) << std::scientific
405 << this->res_.defect/this->prev_defect_
406 << ". Reduction (total): "
407 << std::setw(12) << std::setprecision(4) << std::scientific
408 << this->res_.reduction << std::endl;
409 } // end while
410 } // end try
411 catch(...)
412 {
413 this->res_.elapsed = timer.elapsed();
414 throw;
415 }
416 this->res_.elapsed = timer.elapsed();
417
418 ios_base_all_saver restorer(std::cout); // store old ios flags
419
420 if (this->verbosity_level_ == 1)
421 std::cout << " Newton converged after " << std::setw(2) << this->res_.iterations
422 << " iterations. Reduction: "
423 << std::setw(12) << std::setprecision(4) << std::scientific
424 << this->res_.reduction
425 << " (" << std::setprecision(4) << this->res_.elapsed << "s)"
426 << std::endl;
427
428 if(!this->keep_matrix_)
429 this->A_.reset();
430 } // end apply
431
432 template<class GOS, class TrlV, class TstV>
433 class NewtonTerminate : public virtual NewtonBase<GOS,TrlV,TstV>
434 {
435 typedef GOS GridOperator;
436 typedef TrlV TrialVector;
437
438 typedef typename TstV::ElementType RFType;
439
440 public:
441 NewtonTerminate(const GridOperator& go, TrialVector& u_)
442 : NewtonBase<GOS,TrlV,TstV>(go,u_)
443 , maxit_(40)
444 , force_iteration_(false)
445 {
446 this->reduction_ = 1e-8;
447 this->abs_limit_ = 1e-12;
448 }
449
450 NewtonTerminate(const GridOperator& go)
451 : NewtonBase<GOS,TrlV,TstV>(go)
452 , maxit_(40)
453 , force_iteration_(false)
454 {
455 this->reduction_ = 1e-8;
456 this->abs_limit_ = 1e-12;
457 }
458
459 void setReduction(RFType reduction)
460 {
461 this->reduction_ = reduction;
462 }
463
464 void setMaxIterations(unsigned int maxit)
465 {
466 maxit_ = maxit;
467 }
468
469 void setForceIteration(bool force_iteration)
470 {
471 force_iteration_ = force_iteration;
472 }
473
474 void setAbsoluteLimit(RFType abs_limit_)
475 {
476 this->abs_limit_ = abs_limit_;
477 }
478
479 virtual bool terminate() override
480 {
481 if (force_iteration_ && this->res_.iterations == 0)
482 return false;
483 this->res_.converged = this->res_.defect < this->abs_limit_
484 || this->res_.defect < this->res_.first_defect * this->reduction_;
485 if (this->res_.iterations >= maxit_ && !this->res_.converged)
486 DUNE_THROW(NewtonNotConverged,
487 "NewtonTerminate::terminate(): Maximum iteration count reached");
488 return this->res_.converged;
489 }
490
491 private:
492 unsigned int maxit_;
493 bool force_iteration_;
494 }; // end class NewtonTerminate
495
496 template<class GOS, class TrlV, class TstV>
497 class NewtonPrepareStep : public virtual NewtonBase<GOS,TrlV,TstV>
498 {
499 typedef GOS GridOperator;
500 typedef TrlV TrialVector;
501
502 typedef typename TstV::ElementType RFType;
503 typedef typename GOS::Traits::Jacobian Matrix;
504
505 public:
506 NewtonPrepareStep(const GridOperator& go, TrialVector& u_)
507 : NewtonBase<GOS,TrlV,TstV>(go,u_)
508 , min_linear_reduction_(1e-3)
509 , fixed_linear_reduction_(0.0)
510 , reassemble_threshold_(0.0)
511 {}
512
513 NewtonPrepareStep(const GridOperator& go)
514 : NewtonBase<GOS,TrlV,TstV>(go)
515 , min_linear_reduction_(1e-3)
516 , fixed_linear_reduction_(0.0)
517 , reassemble_threshold_(0.0)
518 , hanging_node_modifications_(false)
519 {}
520
527 void setMinLinearReduction(RFType min_linear_reduction)
528 {
529 min_linear_reduction_ = min_linear_reduction;
530 }
531
536 void setFixedLinearReduction(bool fixed_linear_reduction)
537 {
538 fixed_linear_reduction_ = fixed_linear_reduction;
539 }
540
548 void setReassembleThreshold(RFType reassemble_threshold)
549 {
550 reassemble_threshold_ = reassemble_threshold;
551 }
552
553 void setHangingNodeModifications(bool b)
554 {
555 hanging_node_modifications_ = b;
556 }
557
558 virtual void prepare_step(Matrix& A, TstV& ) override
559 {
560 this->reassembled_ = false;
561 if (this->res_.defect/this->prev_defect_ > reassemble_threshold_)
562 {
563 if (hanging_node_modifications_){
564 auto dirichletValues = *this->u_;
565 // Set all non dirichlet values to zero
566 Dune::PDELab::set_shifted_dofs(this->gridoperator_.localAssembler().trialConstraints(), 0.0, dirichletValues);
567 // Set all constrained DOFs to zero in solution
568 Dune::PDELab::set_constrained_dofs(this->gridoperator_.localAssembler().trialConstraints(), 0.0, *this->u_);
569 // Copy correct Dirichlet values back into solution vector
570 Dune::PDELab::copy_constrained_dofs(this->gridoperator_.localAssembler().trialConstraints(), dirichletValues, *this->u_);
571 // Interpolate periodic constraints / hanging nodes
572 this->gridoperator_.localAssembler().backtransform(*this->u_);
573 }
574
575 if (this->verbosity_level_ >= 3)
576 std::cout << " Reassembling matrix..." << std::endl;
577 A = 0.0;
578 this->gridoperator_.jacobian(*this->u_, A);
579 this->reassembled_ = true;
580 }
581
582 if (fixed_linear_reduction_ == true)
583 this->linear_reduction_ = min_linear_reduction_;
584 else {
585 // determine maximum defect, where Newton is converged.
586 RFType stop_defect =
587 std::max(this->res_.first_defect * this->reduction_,
588 this->abs_limit_);
589
590 /*
591 To achieve second order convergence of newton
592 we need a linear reduction of at least
593 current_defect^2/prev_defect^2.
594 For the last newton step a linear reduction of
595 1/10*end_defect/current_defect
596 is sufficient for convergence.
597 */
598 if ( stop_defect/(10*this->res_.defect) >
599 this->res_.defect*this->res_.defect/(this->prev_defect_*this->prev_defect_) )
600 this->linear_reduction_ =
601 stop_defect/(10*this->res_.defect);
602 else
603 this->linear_reduction_ =
604 std::min(min_linear_reduction_,this->res_.defect*this->res_.defect/(this->prev_defect_*this->prev_defect_));
605 }
606
607 this->prev_defect_ = this->res_.defect;
608
609 ios_base_all_saver restorer(std::cout); // store old ios flags
610
611 if (this->verbosity_level_ >= 3)
612 std::cout << " requested linear reduction: "
613 << std::setw(12) << std::setprecision(4) << std::scientific
614 << this->linear_reduction_ << std::endl;
615 }
616
617 private:
618 RFType min_linear_reduction_;
619 bool fixed_linear_reduction_;
620 RFType reassemble_threshold_;
621 bool hanging_node_modifications_;
622 }; // end class NewtonPrepareStep
623
624 template<class GOS, class TrlV, class TstV>
625 class NewtonLineSearch : public virtual NewtonBase<GOS,TrlV,TstV>
626 {
627 typedef GOS GridOperator;
628 typedef TrlV TrialVector;
629 typedef TstV TestVector;
630
631 typedef typename TestVector::ElementType RFType;
632
633 public:
634 enum Strategy {
636 noLineSearch,
640 hackbuschReusken,
642 hackbuschReuskenAcceptBest };
643
644 NewtonLineSearch(const GridOperator& go, TrialVector& u_)
645 : NewtonBase<GOS,TrlV,TstV>(go,u_)
646 , strategy_(hackbuschReusken)
647 , maxit_(10)
648 , damping_factor_(0.5)
649 {}
650
651 NewtonLineSearch(const GridOperator& go)
652 : NewtonBase<GOS,TrlV,TstV>(go)
653 , strategy_(hackbuschReusken)
654 , maxit_(10)
655 , damping_factor_(0.5)
656 {}
657
658 void setLineSearchStrategy(Strategy strategy)
659 {
660 strategy_ = strategy;
661 }
662
663 void setLineSearchStrategy(std::string strategy)
664 {
665 strategy_ = strategyFromName(strategy);
666 }
667
668 void setLineSearchMaxIterations(unsigned int maxit)
669 {
670 maxit_ = maxit;
671 }
672
673 void setLineSearchDampingFactor(RFType damping_factor)
674 {
675 damping_factor_ = damping_factor;
676 }
677
678 virtual void line_search(TrialVector& z, TestVector& r) override
679 {
680 if ((strategy_ == noLineSearch) || (this->res_.defect < this->abs_limit_))
681 {
682 this->u_->axpy(-1.0, z);
683 this->defect(r);
684 return;
685 }
686
687 if (this->verbosity_level_ >= 4)
688 std::cout << " Performing line search..." << std::endl;
689 RFType lambda = 1.0;
690 RFType best_lambda = 0.0;
691 RFType best_defect = this->res_.defect;
692 TrialVector prev_u(*this->u_);
693 unsigned int i = 0;
694 ios_base_all_saver restorer(std::cout); // store old ios flags
695
696 while (1)
697 {
698 if (this->verbosity_level_ >= 4)
699 std::cout << " trying line search damping factor: "
700 << std::setw(12) << std::setprecision(4) << std::scientific
701 << lambda
702 << std::endl;
703
704 this->u_->axpy(-lambda, z);
705 try {
706 this->defect(r);
707 }
708 catch (NewtonDefectError&)
709 {
710 if (this->verbosity_level_ >= 4)
711 std::cout << " NaNs detected" << std::endl;
712 } // ignore NaNs and try again with lower lambda
713
714 if (this->res_.defect <= (1.0 - lambda/4) * this->prev_defect_)
715 {
716 if (this->verbosity_level_ >= 4)
717 std::cout << " line search converged" << std::endl;
718 break;
719 }
720
721 if (this->res_.defect < best_defect)
722 {
723 best_defect = this->res_.defect;
724 best_lambda = lambda;
725 }
726
727 if (++i >= maxit_)
728 {
729 if (this->verbosity_level_ >= 4)
730 std::cout << " max line search iterations exceeded" << std::endl;
731 switch (strategy_)
732 {
733 case hackbuschReusken:
734 *this->u_ = prev_u;
735 this->defect(r);
736 DUNE_THROW(NewtonLineSearchError,
737 "NewtonLineSearch::line_search(): line search failed, "
738 "max iteration count reached, "
739 "defect did not improve enough");
740 case hackbuschReuskenAcceptBest:
741 if (best_lambda == 0.0)
742 {
743 *this->u_ = prev_u;
744 this->defect(r);
745 DUNE_THROW(NewtonLineSearchError,
746 "NewtonLineSearch::line_search(): line search failed, "
747 "max iteration count reached, "
748 "defect did not improve in any of the iterations");
749 }
750 if (best_lambda != lambda)
751 {
752 *this->u_ = prev_u;
753 this->u_->axpy(-best_lambda, z);
754 this->defect(r);
755 }
756 break;
757 case noLineSearch:
758 break;
759 }
760 break;
761 }
762
763 lambda *= damping_factor_;
764 *this->u_ = prev_u;
765 }
766 if (this->verbosity_level_ >= 4)
767 std::cout << " line search damping factor: "
768 << std::setw(12) << std::setprecision(4) << std::scientific
769 << lambda << std::endl;
770 } // end line_search
771
772 protected:
774 Strategy strategyFromName(const std::string & s) {
775 if (s == "noLineSearch")
776 return noLineSearch;
777 if (s == "hackbuschReusken")
778 return hackbuschReusken;
779 if (s == "hackbuschReuskenAcceptBest")
780 return hackbuschReuskenAcceptBest;
781 DUNE_THROW(Exception, "unknown line search strategy" << s);
782 }
783
784 private:
785 Strategy strategy_;
786 unsigned int maxit_;
787 RFType damping_factor_;
788 }; // end class NewtonLineSearch
789
790 template<class GOS, class S, class TrlV, class TstV = TrlV>
791 class Newton : public NewtonSolver<GOS,S,TrlV,TstV>
792 , public NewtonTerminate<GOS,TrlV,TstV>
793 , public NewtonLineSearch<GOS,TrlV,TstV>
794 , public NewtonPrepareStep<GOS,TrlV,TstV>
795 {
796 typedef GOS GridOperator;
797 typedef S Solver;
798 typedef TrlV TrialVector;
799
800 public:
801 Newton(const GridOperator& go, TrialVector& u_, Solver& solver_)
802 DUNE_DEPRECATED_MSG("This Newton is deprecated. Use NewtonMethod from dune/pdelab/solver/newton.hh instead.")
803 : NewtonBase<GOS,TrlV,TstV>(go,u_)
804 , NewtonSolver<GOS,S,TrlV,TstV>(go,u_,solver_)
805 , NewtonTerminate<GOS,TrlV,TstV>(go,u_)
806 , NewtonLineSearch<GOS,TrlV,TstV>(go,u_)
807 , NewtonPrepareStep<GOS,TrlV,TstV>(go,u_)
808 {}
809 Newton(const GridOperator& go, Solver& solver_)
810 DUNE_DEPRECATED_MSG("This Newton is deprecated. Use NewtonMethod from dune/pdelab/solver/newton.hh instead.")
811 : NewtonBase<GOS,TrlV,TstV>(go)
812 , NewtonSolver<GOS,S,TrlV,TstV>(go,solver_)
813 , NewtonTerminate<GOS,TrlV,TstV>(go)
814 , NewtonLineSearch<GOS,TrlV,TstV>(go)
815 , NewtonPrepareStep<GOS,TrlV,TstV>(go)
816 {}
818
839 void setParameters(const Dune::ParameterTree & param)
840 {
841 typedef typename TstV::ElementType RFType;
842 if (param.hasKey("VerbosityLevel"))
843 this->setVerbosityLevel(
844 param.get<unsigned int>("VerbosityLevel"));
845 if (param.hasKey("Reduction"))
846 this->setReduction(
847 param.get<RFType>("Reduction"));
848 if (param.hasKey("MaxIterations"))
849 this->setMaxIterations(
850 param.get<unsigned int>("MaxIterations"));
851 if (param.hasKey("ForceIteration"))
852 this->setForceIteration(
853 param.get<bool>("ForceIteration"));
854 if (param.hasKey("AbsoluteLimit"))
855 this->setAbsoluteLimit(
856 param.get<RFType>("AbsoluteLimit"));
857 if (param.hasKey("MinLinearReduction"))
858 this->setMinLinearReduction(
859 param.get<RFType>("MinLinearReduction"));
860 if (param.hasKey("FixedLinearReduction"))
861 this->setFixedLinearReduction(
862 param.get<bool>("FixedLinearReduction"));
863 if (param.hasKey("ReassembleThreshold"))
864 this->setReassembleThreshold(
865 param.get<RFType>("ReassembleThreshold"));
866 if (param.hasKey("LineSearchStrategy"))
867 this->setLineSearchStrategy(
868 param.get<std::string>("LineSearchStrategy"));
869 if (param.hasKey("LineSearchMaxIterations"))
870 this->setLineSearchMaxIterations(
871 param.get<unsigned int>("LineSearchMaxIterations"));
872 if (param.hasKey("LineSearchDampingFactor"))
873 this->setLineSearchDampingFactor(
874 param.get<RFType>("LineSearchDampingFactor"));
875 if (param.hasKey("KeepMatrix"))
876 this->setKeepMatrix(
877 param.get<bool>("KeepMatrix"));
878 if (param.hasKey("UseMaxNorm"))
879 this->setUseMaxNorm(
880 param.get<bool>("UseMaxNorm"));
881 }
882 }; // end class Newton
883 } // end namespace PDELab
884} // end namespace Dune
885
886#endif // DOXYGEN
887
888#endif // DUNE_PDELAB_NEWTON_NEWTON_HH
Hierarchical structure of string parameters.
Definition: parametertree.hh:35
std::string get(const std::string &key, const std::string &defaultValue) const
get value as string
Definition: parametertree.cc:183
bool hasKey(const std::string &key) const
test for key
Definition: parametertree.cc:46
A few common exception classes.
decltype(auto) apply(F &&f, ArgTuple &&args)
Apply function with arguments given as tuple.
Definition: apply.hh:46
#define DUNE_DEPRECATED_MSG(text)
Mark some entity as deprecated.
Definition: deprecated.hh:169
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
void set_constrained_dofs(const CG &cg, typename XG::ElementType x, XG &xg)
construct constraints from given boundary condition function
Definition: constraints.hh:796
void set_shifted_dofs(const CG &cg, typename XG::ElementType x, XG &xg)
Definition: constraints.hh:1014
void copy_constrained_dofs(const CG &cg, const XG &xgin, XG &xgout)
Definition: constraints.hh:936
auto min(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::min()
Definition: defaults.hh:87
auto max(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::max()
Definition: defaults.hh:79
Utility class for storing and resetting stream attributes.
Dune namespace.
Definition: alignedallocator.hh:14
A hierarchical structure of string parameters.
Standard Dune debug streams.
A simple timing class.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)