KASKADE 7 development version
nleq_err.hh
Go to the documentation of this file.
1/*
2 nleqErr - Error-based Damped Newton algorithm
3
4 * Written by L. Weimann
5 * Purpose solution of systems of nonlinear equations
6 * Method ERRor-based Damped Newton algorithm
7 (see reference below)
8 * Category F2a. - Systems of nonlinear equations
9 * Keywords Nonlinear equations, Newton methods, Finite elements
10 * Version 2.0
11 * Revision April 2014
12 * Latest Change May 2014
13 * Library Kaskade7
14 * Code C++, Double Precision
15 * Environment Standard C environment on PC's,
16 workstations and hosts.
17 * Copyright (c) Konrad-Zuse-Zentrum fuer
18 Informationstechnik Berlin (ZIB)
19 Takustrasse 7, D-14195 Berlin-Dahlem
20 phone : + 49/30/84185-0
21 fax : + 49/30/84185-125
22 * Contact Lutz Weimann
23 ZIB, Division Scientific Computing,
24 Department Numerical Analysis and Modelling
25 phone : + 49/30/84185-185
26 fax : + 49/30/84185-107
27 e-mail: weimann@zib.de
28
29 * References:
30
31 /1/ P. Deuflhard:
32 Newton Methods for Nonlinear Problems. -
33 Affine Invariance and Adaptive Algorithms.
34 Series Computational Mathematics 35, Springer (2004)
35
36 ---------------------------------------------------------------
37
38 * Licence
39 KASKADE 7 is distributed under the terms of the ZIB Academic License.
40 see $KASKADE/academic.txt
41
42 ------------------------------------------------------------
43
44 * Class description
45 =================
46
47 The calling interface looks as follows:
48
49 template<class Grid, class Equation, class VariableSet, class Spaces>
50 class NleqSolver
51
52 Public types are:
53
54 typedef enum {none=0, minimum=1, verbose=2, debug=3} PrintLevel
55
56 typedef enum {mildlyNonlinear=2, highlyNonlinear=3, extremelyNonlinear=4}
57 NonlinProblemType
58
59 struct NleqInfo
60 {
61 double precision, normDx;
62 std::vector<double> *fx, *dx;
63 int noIterations, returnCode, subCode, noFunctionEvaluations, noJacobianEvaluations;
64 }
65
66 Public methods are:
67
68 void setTolerance( double tol )
69 tol is of type double and must be the error tolerance which
70 the final approximate solution x^k must fit.
71
72 void setNonlinProblemType(NonlinProblemType nonlinType )
73 Sets the problem type of the nonlinear problem.
74 The following classifications may be used:
75 mildlyNonlinear: The problem is considered to be mildly nonlinear and
76 NleqSolver starts up with dampingfactor=1.
77 highlyNonlinear: The problem is considered to be highly nonlinear and
78 NleqSolver starts up with dampingfactor=1.0e-4.
79 extremelyNonlinear: The problem is considered to be extremely nonlinear
80 and NleqSolver starts up with dampingfactor=1.0e-6.
81 Moreover, restricted is set automatically to true.
82
83 void setMaximumNoIterations( int maximumIter )
84 maximumIter is of type int and must contain the maximum number of allowed
85 Newton iterations. if a zero or negative value is supplied, then the maximum
86 iteration count will be set to 50.
87
88 void setPreconFillLevel( int preconFillLevel )
89 preconFillLevel is of type int and must contain the PrecondType::ILUK preconditioners
90 filllevel (fill-in level).
91
92 void setRestricted( bool restricted )
93 restricted is of type bool.
94 If set to true, then the restricted monotonicity test will be applied for
95 determination whether the next iterate (and the associate damping factor
96 lambda) will be accepted. This means, with
97 theta = ||dxBar(k+1)|| / ||dx(k)||,
98 (where dx(k) denotes the k-th Newton correction, and dxBar(k+1) denotes
99 the sucessive simplified Newton correction)
100 the condition theta <= 1.0 - lambda/4 must be fit.
101 If set to false, then the standard monotonicity test will be applied, i.e.
102 the following condition must be fit:
103 theta < 1.0.
104
105 void setErrorStream( std::ostream& errorStream )
106 errorStream is of type pointer to std::ostream, as defined by the <iostream>
107 header file. It must be set either to a NULL pointer, std::cout, std::cerr,
108 or to another file pointer which has been initialized by a fopen call.
109 If it is set to NULL, errorStream will be set to std:cerr. The error
110 messages will be printed to errorStream.
111
112 void setMonitorStream( std::ostream& monitorStream )
113 monitorStream is of type pointer to std::ostream, as defined by the <iostream>
114 header file. It must be set either to a NULL pointer, std::cout, std::cerr,
115 or to another file pointer which has been initialized by a fopen call.
116 If it is set to NULL, monitorStream will be set to std::cout. The monitor
117 output will be printed to monitorStream.
118
119 void setErrorLevel( PrintLevel errorLevel )
120 errorLevel is of type PrintLevel. If it is set to level none,
121 then no error message will be printed if an error condition occurs.
122 If it is set to level minimum or any higher level, then error messages
123 will be printed, if appropriate.
124
125 void setMonitorLevel( PrintLevel monitorLevel )
126 monitorLevel is of type PrintLevel. If it is set to level none,
127 then no monitor output will be printed.
128 If it is set to level minimum, a few infomation will be printed.
129 If set to level verbose, then some infomation about each Newton iteration
130 step, fitting into a single line, will be printed. The higher level debug
131 is reserved for future additional information output.
132
133 void setDataLevel( PrintLevel dataLevel )
134 dataLevel is of type PrintLevel.
135 If it is set to level none, then no data output will be done.
136 If it is set to level minimum, the initial values and the final
137 values of the iteration vector x will be output to a file named
138 "<outFilePrefix>mmm.vtu" in vtu-format.
139 If it is set to level verbose or any higher level, then each Newton iterate
140 x will be output to a file named "<outFilePrefix>nnn.vtu" in vtu-format.
141
142 void setOutFilePrefix( const std::string& outFilePrefix )
143 outFilePrefix is a filename prefix used for the .vtu output file
144 for each iterate. The complete filename for the k-th iterate output
145 is outFilePrefinnn.vtu, where nnn is the value of k filled with leading
146 zeros for k<100.
147
148 void setScalingVector( std::vector<double>* scale )
149 scale is of type pointer to a std::vector<double> of size n.
150 *scale must, if scale is not the NULL pointer, contain positive scaling
151 values, which are used in computations of scaled norms, as follows:
152 || x || = squareroot(sum(1 to n) ( x_i/scale_i )^2)
153 The pointer may be initialized with a NULL pointer. In this case, all
154 scaling values are internally set to a default value, which depends on
155 the value of nonlinType.
156
157 struct NleqInfo getInfo()
158 returns some info about the Newton iteration and final Newton correction
159 and residuum vector.
160 In detail:
161 info.precision is of type double and is set to the achieved scaled norm
162 of the error of the final iterate.
163
164 info.normDx is of type double and is set to the unscaled norm of the
165 last Newton correction.
166
167 info.fx is a pointer to a double array of size n, which contains the
168 final residuum vector.
169
170 info.noIterations is set to number of Newton iteration steps done.
171
172 info.noLiniterIterations ist set to the total number of linear solver iterations
173 done.
174
175 info.noFunctionEvaluations is set to the number of done evaluations of the right-
176 hand side of the linearized system.
177
178 info.noJacobianEvaluations is set to the number of computations of the Jacobian
179 of the linearized system.
180
181 info.returnCode is set to the return-code of nleq_err. A return-code 0
182 means that nleq_err has terminated sucessfully. For the meaning of a
183 nonzero return-code, see the error messages list below.
184
185 info.subCode is set for certain failure conditions to the error code
186 which has been returned by a routine called from nleq_err.
187
188 The following error conditions may occur: (returned via info.returnCode)
189 --------------------------------------------------------------------
190
191 1 Singular Jacobian matrix (not yet realized),
192 nleqErr cannot proceed the iteration.
193 2 Maximum number of Newton iteration (as set by maximumNoIterations) exceeded.
194 3 No convergence of Newton iteration, damping factor became too small.
195 4 Linear solver Dune::BiCGSTABSolver failed to converge when computing
196 the ordinary Newton-correction.
197 5 Linear solver Dune::BiCGSTABSolver failed to converge when computing
198 the simplified Newton-correction.
199 21 Nonpositive value for xtol supplied.
200 22 Negative scaling value for some component of vector *scale
201 supplied.
202
203 void nleqErr(GridManager<Grid>& gridManager,
204 Equation& eq,
205 VariableSet const& variableSet,
206 typename VariableSet::VariableSet* x,
207 Spaces const& spaces)
208
209 A short description of the parameters of nleqErr follows:
210
211 GridManager<Grid>& gridManager:
212 The grid obtained by discretization (see Kaskade7 documentation).
213
214 Equation& eq:
215 The structure eq defining the Weak-formulation equation and boundary
216 conditions mainly by the class-menbers DomainCache::d1, DomainCache::d2,
217 BoundaryCache::d1 and BoundaryCache::d2. For details, consult the
218 Kaskade7 documentation.
219
220 VariableSet const& variableSet:
221 For details, consult the Kaskade7 documentation.
222
223 VariableSet::VariableSet* x:
224 x must contain on input an initial guess of the problems solution,
225 which is used as the start-vector of the damped Newton iteration.
226 On output, the pointed array contains an approximate solution vector x^k,
227 which fits the error condition
228 || x^k - x* || <= xtol,
229 where x* denotes the exact solution, and ||...|| is a scaled
230 Euclidian norm.
231 For the class member VariableSet::VariableSet, consult the Kaskade7
232 documentation.
233
234 Spaces const& spaces:
235 For details, consult the Kaskade7 documentation.
236
237 Summary of changes:
238 -------------------
239
240 Version Date Changes
241 2.0 2014/04/29 Special version for use with Kaskade7.2
242 1.1.1 2006/06/06 Missing int return code in function
243 nleqErrInitScale, bug fixed.
244 1.1 2006/06/02 Added the output data files iterfile, resfile and
245 miscfile, where optional data output is provided,
246 a single line, starting with the iteration number,
247 for each iteration step.
248 1.0 2006/05/30 initial release.
249
250*/
251
252#ifndef NLEQERR_HH
253#define NLEQERR_HH
254
255#include <cstdlib>
256#include <iostream>
257#include <vector>
258#include <cmath>
259#include <algorithm>
260#include <cassert>
261
262#include "fem/assemble.hh"
263#include "fem/istlinterface.hh"
264#include "fem/functional_aux.hh"
265#include "fem/gridmanager.hh"
266#include "linalg/iluprecond.hh"
267#include "io/vtk.hh"
268#include "utilities/timing.hh"
269
270#ifndef MACHCONST_
271#define MACHCONST_
272#define SMALL DBL_EPSILON
273#define EPMACH DBL_MIN
274#endif
275
276namespace Kaskade
277{
288 template<class Grid, class Equation, class VariableSet, class Spaces>
290 {
291 public:
292 typedef enum {
296 debug=3
297 }
298 PrintLevel ;
303 typedef enum {
330 struct NleqInfo
331 {
333 std::vector<double> *fx, *dx;
336 };
337
338 private:
339 typedef enum {initial=1,intermediate=2,solution=3,final=4} OutputMode;
340 struct NleqData
341 {
342 std::vector<double> *fx, *dx;
343 double normF, normDx, normDxBar, lambda, theta;
344 OutputMode mode;
345 };
346
347 typedef typename Grid::LeafGridView LeafView;
348 typedef typename VariableSet::VariableSet VariableSetRepresentation;
349
350 #define THETA_MAX 0.5
351 #define MAX_ITER_DEFAULT 50
352 #define LAMBDA_START_DEFAULT 1.0e-2
353 #define LAMBDA_START_EXTREMELY_DEFAULT 1.0e-4
354 #define LAMBDA_MIN_DEFAULT 1.0e-4
355 #define LAMBDA_MIN_EXTREMELY_DEFAULT 1.0e-8
356
357 public:
358
360 {
361 xtol = 1.0e-5;
362 nonlinType = highlyNonlinear;
363 maximumNoIterations = 50;
364 restricted = false;
365 preconFillLevel=0;
366 errorStream = &(std::cerr);
367 monitorStream = &(std::cout);
368 errorLevel = verbose;
369 monitorLevel = none;
370 dataLevel = none;
371 outFilePrefix = "iter_";
372 scale = new std::vector<double>(0);
373 }
374
380 void setTolerance( double tol_ ) { xtol=tol_; }
381
394 void setNonlinProblemType(NonlinProblemType nonlinType_ ) { nonlinType=nonlinType_; }
395
400 void setMaximumNoIterations( int maximumIter_ ) { maximumNoIterations=maximumIter_; }
401
406 void setPreconFillLevel( int preconFillLevel_ ) { preconFillLevel=preconFillLevel_; }
407
423 void setRestricted( bool restricted_ ) { restricted=restricted_; }
424
430 void setErrorStream( std::ostream& errorStream_ ) { errorStream=&errorStream_; }
431
437 void setMonitorStream( std::ostream& monitorStream_ ) { monitorStream=&monitorStream_; }
438
444 void setErrorLevel( PrintLevel errorLevel_ ) { errorLevel=errorLevel_; }
445
451 void setMonitorLevel( PrintLevel monitorLevel_ ) { monitorLevel=monitorLevel_; }
452
458 void setDataLevel( PrintLevel dataLevel_ ) { dataLevel=dataLevel_; }
459
465 void setStatistics( bool statistics_ ) { statistics=statistics_; }
466
473 void setOutFilePrefix( const std::string& outFilePrefix_ ) { outFilePrefix=outFilePrefix_; }
474
479 void setScalingVector( std::vector<double>* scale_ )
480 {
481 delete scale;
482 if (scale_) scale=scale_;
483 }
484
488 struct NleqInfo getInfo() { return info; }
489
502 void nleqErr(GridManager<Grid>& gridManager,
503 Equation& eq,
504 VariableSet const& variableSet,
505 typename VariableSet::VariableSet* x,
506 Spaces const& spaces, Timings& timer=Timings::instance())
507 {
508 double lambda, lambdaNew, mue, normFk, normFkPlusOne, normDxkMinusOne,
509 normDxBar, normDx, theta, s;
510 double lambdaMin;
511 int const nvars = Equation::AnsatzVars::noOfVariables;
512 int const n = variableSet.degreesOfFreedom(0,nvars);
513 int iterationCounter=0, fail=0;
514 bool reducted;
515 std::vector<double> dxdata(n), dxBar(n), xThresh(n), w(n), xData(n);
516 std::vector<double> *fxk = new std::vector<double>(n);
517 int noRHSComputations=0, noJacobianComputations=0, noLinearSolverIterations=0;
518 struct NleqData *data = new struct NleqData;
519 if (!data)
520 {
521 std::cerr << std::endl << " could not allocate struct data" << std::endl;
522 info.returnCode=-994; return;
523 };
524 data->theta = 0.0;
525 data->mode = initial;
526
527 if ( monitorLevel > 0 )
528 *monitorStream << std::endl << " nleqErr - Version 2.0" << std::endl;
529 if ( maximumNoIterations <= 0 ) maximumNoIterations = MAX_ITER_DEFAULT;
530 if ( nonlinType==mildlyNonlinear )
531 {
532 lambda = 1.0; lambdaMin = LAMBDA_MIN_DEFAULT;
533 }
534 else if ( nonlinType==highlyNonlinear )
535 {
536 lambda = LAMBDA_START_DEFAULT; lambdaMin = LAMBDA_MIN_DEFAULT;
537 }
538 else if ( nonlinType==extremelyNonlinear )
539 {
542 restricted = true;
543 };
544
545 info.returnCode = nleqParcheckAndPrint(n);
546 if ( info.returnCode !=0 )
547 {
548 if (data) delete data;
549 return;
550 };
551
552 LeafView leafGridView = gridManager.grid().leafGridView();
553 Dune::InverseOperatorResult res;
555 Assembler assembler(spaces);
556 typename VariableSet::VariableSet dx(variableSet);
557 typename VariableSet::VariableSet tmp(variableSet);
558 typename VariableSet::VariableSet xkPlusOne(variableSet);
559 int const neq = Equation::TestVars::noOfVariables;
560 size_t nnz = assembler.nnz(0,neq,0,nvars,false);
561 if ( monitorLevel > 0 )
562 *monitorStream << " nvars=" << nvars << ", neq=" << neq << ", nnz=" << nnz << "\n";
563 typedef typename VariableSet::template CoefficientVectorRepresentation<0,neq>::type CoefficientVectors;
564 CoefficientVectors theSolution(VariableSet::template CoefficientVectorRepresentation<0,neq>::init(spaces));
566
567 x->write(xData.begin());
568 if ( monitorLevel > 1 )
569 *monitorStream << std::endl
570 << "| Newton iteration |iterative linear solver|" << std::endl
571 << " iter normScl(dx) norm(fk) lambda res niter rate "
572 << std::endl << std::endl;
573 normDx = 0.0; normDxBar = 0.0;
574 w=xData; xThresh=*scale;
575 info.returnCode = 2;
576
577 do
578 {
579 nleqErrRescale(*scale,xData,w,xThresh);
580 if ( iterationCounter>0 )
581 // recompute norms after rescaling
582 {
583 normDxkMinusOne = nleqScaledNorm2(dxdata,*scale);
584 normDxBar = nleqScaledNorm2(dxBar,*scale);
585 };
586 if (statistics) timer.start("time for assemble");
587 assembler.assemble(linearization(eq,*x));
588 if (statistics) timer.stop("time for assemble");
589 noRHSComputations++; noJacobianComputations++;
590 CoefficientVectors fx(assembler.rhs());
591 fx.write(fxk->begin());
592 normFk = nleqNorm2(*fxk);
594
595 int iteSteps = 1000;
596 double iteEps = xtol*1.0e-2;
597 typedef typename VariableSet::template CoefficientVectorRepresentation<0,neq>::type LinearSpace;
598 if (statistics) timer.start("time for preconditioner setup");
600 if (statistics) timer.stop("time for preconditioner setup");
601 Dune::BiCGSTABSolver<LinearSpace> cg(A,iluk,iteEps,iteSteps,0);
602 theSolution = 0;
603 if (statistics) timer.start("time for linear solver BiCGSTAB");
604 cg.apply(theSolution,fx,res);
605 if (statistics) timer.stop("time for linear solver BiCGSTAB");
606 noLinearSolverIterations += res.iterations;
607 if ( !res.converged ) { info.returnCode=4; break; };
608 dx.data = theSolution.data;
609 dx.write(dxdata.begin());
610 normDx = nleqScaledNorm2(dxdata,*scale);
611 if ( monitorLevel > 1 )
612 nleqErrMonitor(iterationCounter,normDx,normFk,lambda,' ',res);
613 if ( normDx <= xtol ) /* solution found, if condition is true */
614 {
615 data->normF = normFk; data->normDx = normDx;
616 data->normDxBar = normDxBar; data->lambda = lambda;
617 if (statistics) timer.start("time for writing output data");
618 nleqDataOut(iterationCounter,leafGridView,*x,data);
619 if (statistics) timer.stop("time for writing output data");
620 *x += dx; iterationCounter++;
621 info.returnCode=0; break;
622 };
623 if ( iterationCounter>0 )
624 {
625 for (int i=0;i<n;i++) w[i] = dxBar[i]-dxdata[i];
626 s = nleqScaledNorm2(w,*scale);
627 mue = (normDxkMinusOne*normDxBar)/(s*normDx) * lambda;
628 lambda = std::min(1.0,mue);
629 };
630 reducted = false;
631
632 bool doCorrectorLoop=true;
633 do
634 {
635 if ( lambda < lambdaMin ) { info.returnCode=3; break; }; // stop, convergence failure!
636 tmp = dx;
637 tmp *= -lambda;
638 xkPlusOne=*x; xkPlusOne += tmp; /* new trial iterate */
639 if (statistics) timer.start("time for assemble");
640 assembler.assemble(linearization(eq,xkPlusOne),assembler.RHS);
641 if (statistics) timer.stop("time for assemble");
642 noRHSComputations++;
643 CoefficientVectors fxq(assembler.rhs());
644 fxq.write(fxk->begin());
645
646 normFkPlusOne = nleqNorm2(*fxk);
647 dxBar=*fxk;
648 theSolution = 0;
649 if (statistics) timer.start("time for linear solver BiCGSTAB");
650 cg.apply(theSolution,fxq,res);
651 if (statistics) timer.stop("time for linear solver BiCGSTAB");
652 noLinearSolverIterations += res.iterations;
653 if ( !res.converged ) { info.returnCode=5; break; };
654 tmp.data = theSolution.data;
655 tmp.write(dxBar.begin());
656 normDxBar = nleqScaledNorm2(dxBar,*scale);
657 if ( monitorLevel > 1 )
658 nleqErrMonitor(iterationCounter,normDxBar,normFkPlusOne,lambda,'*',res);
659 theta = normDxBar/normDx;
660 s = 1.0-lambda;
661 for (int i=0;i<n;i++) w[i] = dxBar[i]-s*dxdata[i];
662 mue = (0.5*normDx*lambda*lambda) / nleqScaledNorm2(w,*scale);
663 if ( ( !restricted && theta >= 1.0 ) ||
664 ( restricted && theta > 1.0-lambda/4.0) )
665 {
666 lambdaNew = std::min(mue,0.5*lambda);
667 if ( lambda <= lambdaMin ) lambda = lambdaNew;
668 else lambda = std::max(lambdaNew,lambdaMin);
669 reducted = true;
670 continue;
671 };
672 lambdaNew = std::min(1.0,mue);
673 if ( lambda==1.0 && lambdaNew==1.0 )
674 {
675 if ( normDxBar <= xtol )
676 {
677 *x += tmp;
678 info.returnCode=0;
679 break;
680 };
681 }
682 else
683 {
684 if( lambdaNew >= 4.0*lambda && !reducted )
685 {
686 lambda=lambdaNew; continue;
687 };
688 };
689 doCorrectorLoop=false;
690 }
691 while ( doCorrectorLoop );
692 if ( info.returnCode !=2 ) break;
693 data->normF = normFk; data->normDx = normDx;
694 data->normDxBar = normDxBar; data->lambda = lambda;
695 if (statistics) timer.start("time for writing output data");
696 nleqDataOut(iterationCounter,leafGridView,*x,data);
697 if (statistics) timer.stop("time for writing output data");
698 data->mode = intermediate;
699 // save previous iterate for scaling purposes and accept new iterate
700 x->write(w.begin()); *x=xkPlusOne; x->write(xData.begin());
701 // next step
702 iterationCounter++;
703 normFk = normFkPlusOne;
704 }
705 while ( iterationCounter <= maximumNoIterations && info.returnCode == 2 );
706
707 data->normF = normFkPlusOne; data->normDx = normDx;
708 data->normDxBar = normDxBar; data->lambda = lambda;
709 data->mode = ( info.returnCode==0 ? solution : final );
710 if (statistics) timer.start("time for writing output data");
711 nleqDataOut(iterationCounter,leafGridView,*x,data);
712 if (statistics) timer.stop("time for writing output data");
713
714 if ( (monitorLevel > 0) && (info.returnCode==0) )
715 *monitorStream << std::endl <<
716 " solution of nonlinear system obtained within " << iterationCounter << " Newton iteration steps" <<
717 std::endl << " using " << noJacobianComputations << " Jacobian assemblies and " << noRHSComputations <<
718 " function assemblies" << std::endl;
719
720 if ( (errorLevel > 0) && (info.returnCode != 0) )
721 {
722 switch ( info.returnCode )
723 {
724 case 2:
725 *errorStream << std::endl <<
726 " Error - Maximum allowed number of iterations exceeded" << std::endl;
727 break;
728 case 3:
729 *errorStream << std::endl <<
730 " Error - no convergence, damping factor became too small" << std::endl;
731 break;
732 case 4:
733 *errorStream << std::endl <<
734 " Error - no convergence of iterative linear solver for dx computation" <<
735 std::endl;
736 break;
737 case 5:
738 *errorStream << std::endl <<
739 " Error - no convergence of iterative linear solver for dxq computation" << std::endl;
740 break;
741 default :
742 *errorStream << std::endl << " Error, code=" << info.returnCode <<
743 ", subCode=" << fail << std::endl;
744 };
745 };
746 info.subCode = fail;
747 delete data;
748
749 info.precision = normDx;
750 info.normDx = normDx;
751
752 // store info
753 info.noIterations = iterationCounter;
754 info.noFunctionEvaluations = noRHSComputations;
755 info.noJacobianEvaluations = noJacobianComputations;
756 info.noLiniterIterations = noLinearSolverIterations;
757 info.fx = fxk;
758 if (statistics) std::cout << timer << std::endl;
759 }
760
761 private:
762
763 void nleqErrRescale(std::vector<double>& scale, std::vector<double> const & x,
764 std::vector<double> const& xa, std::vector<double> const& xThresh)
765 {
766 int const n=scale.size();
767 assert ( (x.size()==n) && (xa.size()==n) && (xThresh.size()==n) );
768 for (int i=0;i<n;i++)
769 scale[i] = std::max(xThresh[i],std::max(0.5*(std::abs(x[i])+std::abs(xa[i])),SMALL));
770 }
771
772 void nleqErrMonitor(int const iterationCounter, double const normDx,
773 double const normF, double const lambda, char const indicator,
774 Dune::InverseOperatorResult res)
775 {
776 *monitorStream << " " << std::setw(4) << iterationCounter << " " << std::setw(1) << indicator << " "
777 << std::setw(12) << std::setprecision(5) << std::scientific << normDx << " "
778 << std::setw(12) << std::setprecision(5) << normF << " ";
779 monitorStream->unsetf(std::ios::fixed | std::ios::scientific);
780 *monitorStream << std::setw(8) << std::fixed << lambda << " " << std::setw(4)
781 << (res.converged?"conv":"fail") << " " << std::setw(5) << res.iterations << " "
782 << std::setw(8) << res.conv_rate << std::endl;
783 monitorStream->unsetf(std::ios::fixed | std::ios::scientific);
784 }
785
786 double nleqScaledNorm2(std::vector<double> const& v, std::vector<double> const& scale)
787 {
788 int const n=v.size();
789 assert ( scale.size()==n );
790 double t, rval = 0.0;
791 for (int i=0;i<n;i++) {t=v[i]/scale[i]; rval += t*t;};
792 return sqrt( rval / (double)n );
793 }
794
795 double nleqNorm2(std::vector<double> const& v)
796 {
797 int const n=v.size();
798 double rval = 0.0;
799 for (int i=0;i<n;i++) rval += v[i]*v[i];
800 return sqrt( rval / (double)n );
801 }
802
803 void nleqDataOut(int const iterationCounter, LeafView const leafGridView, VariableSetRepresentation const x,
804 struct NleqData const *data)
805 {
806 if ( (dataLevel==none) || ( (dataLevel==minimum) && (data->mode==intermediate) ) )
807 return;
808 // output of solution in VTK format for visualization,
809 // the data are written as ascii stream into file temperature.vtu,
810 // possible is also binary
811 std::ostringstream fname;
812 fname << outFilePrefix;
813 fname.width(3);
814 fname.fill('0');
815 fname.setf(std::ios_base::right,std::ios_base::adjustfield);
816 fname << iterationCounter;
817 fname.flush();
818 writeVTKFile(x,fname.str(),IoOptions());
819 }
820
821 int nleqParcheckAndPrint(int const n)
822 #define TOLMIN EPMACH*1.0e2
823 #define TOLMAX 1.0e-1
824 {
825 double large = 1.0/SMALL, small = SMALL, defaultScale;
826 if ( n<=0 )
827 {
828 if ( errorLevel>0 )
829 *errorStream << std::endl << " Error - Number of Equations/unknowns must be >0" << std::endl;
830 return 20;
831 };
832 if ( xtol <= 0 )
833 {
834 if ( errorLevel>0 )
835 *errorStream << std::endl << " Error - xtol must be positive" << std::endl;
836 return 21;
837 }
838 else
839 {
840 if ( xtol > TOLMAX )
841 {
842 xtol = TOLMAX;
843 if ( errorLevel>1 )
844 *errorStream << std::endl <<
845 " User prescribed RTOL decreased to reasonable largest value RTOL=" <<
846 xtol << std::endl;
847 }
848 else if ( xtol < TOLMIN )
849 {
850 xtol = TOLMIN;
851 if ( errorLevel>1 )
852 *errorStream << std::endl <<
853 "User prescribed RTOL increased to reasonable smallest value RTOL=" <<
854 xtol << std::endl;
855 };
856 };
857 if ( nonlinType >= highlyNonlinear )
858 defaultScale = xtol;
859 else
860 defaultScale = 1.0;
861
862 if ( scale->empty() )
863 {
864 scale->resize(n);
865 for (int i=0;i<n;i++) (*scale)[i]=defaultScale;
866 }
867 else
868 {
869 for (int i=0;i<n;i++)
870 {
871 if ( (*scale)[i] < 0.0 )
872 {
873 if ( errorLevel>0 )
874 *errorStream << std::endl <<
875 " Error - negative value scale[" << i << "] supplied" << std::endl;
876 return 22;
877 }
878 else if ( (*scale)[i] == 0.0 )
879 (*scale)[i] = defaultScale;
880 else if ( (*scale)[i] < SMALL )
881 {
882 if ( errorLevel>1 )
883 *errorStream << std::endl <<
884 " Warning scale[" << i << "] too small - increased to " << SMALL << std::endl;
885 (*scale)[i] = small;
886 }
887 else if ( (*scale)[i] > large )
888 {
889 if ( errorLevel>1 )
890 *errorStream << std::endl <<
891 " Warning scale[" << i << "] too large - decreased to " << large << std::endl;
892 (*scale)[i] = large;
893 };
894 };
895 };
896 if ( monitorLevel==0 ) return 0;
897 *monitorStream << std::endl << " Problem dimension: n = " << n << std::endl;
898 *monitorStream << std::endl << " Prescribed relative precision: " << xtol
899 << std::endl;
900 *monitorStream << " The problem is specified as being ";
901 switch ( nonlinType )
902 {
903 case mildlyNonlinear: *monitorStream << "mildly nonlinear" << std::endl;
904 break;
905 case highlyNonlinear: *monitorStream << "highly nonlinear" << std::endl;
906 break;
907 case extremelyNonlinear: *monitorStream << "extremely nonlinear" << std::endl;
908 break;
909 };
910 if ( restricted )
911 *monitorStream << " The restricted monotonicity test will be applied" << std::endl;
912 else
913 *monitorStream << " The standard monotonicity test will be applied" << std::endl;
914
915 *monitorStream << " The maximum permitted number of iteration steps is: " <<
916 maximumNoIterations << std::endl;
917 return 0;
918 }
919
920 double xtol;
921 int maximumNoIterations, preconFillLevel;
922 bool restricted, statistics;
923 std::ostream *errorStream, *monitorStream;
924 enum {StandardScale=0,StartValueScale=1} scaleopt;
925 PrintLevel errorLevel, monitorLevel, dataLevel;
926 NonlinProblemType nonlinType;
927 std::vector<double>* scale;
928 std::string outFilePrefix;
929 struct NleqInfo info;
930
931 };
932}
933#endif
An adaptor presenting a Dune::LinearOperator <domain_type,range_type> interface to a contiguous sub-b...
Grid const & grid() const
Returns a const reference on the owned grid.
Definition: gridmanager.hh:292
Solution of a nonlinear system of equations by a damped Newton-method.
Definition: nleq_err.hh:290
void setErrorLevel(PrintLevel errorLevel_)
Sets the error-output level. The default error-output level is verbose.
Definition: nleq_err.hh:444
void setScalingVector(std::vector< double > *scale_)
Sets a user-defined scaling-threshold vector.
Definition: nleq_err.hh:479
void setMonitorStream(std::ostream &monitorStream_)
Sets the monitor-output stream. The default monitor-output stream is std::cout.
Definition: nleq_err.hh:437
struct NleqInfo getInfo()
After calling nleqErr, getInfo returns the info structure contents.
Definition: nleq_err.hh:488
void setDataLevel(PrintLevel dataLevel_)
Sets the plot-data-output level. The default plot-data-output level is none.
Definition: nleq_err.hh:458
void setStatistics(bool statistics_)
Sets the Timings statistics flag. The default Timings statistics flag level is off.
Definition: nleq_err.hh:465
void setTolerance(double tol_)
Sets the error tolerance which the final approximate solution must fit. The default value is 1....
Definition: nleq_err.hh:380
void setNonlinProblemType(NonlinProblemType nonlinType_)
Set the classification of the nonlinear problem. The default value is highlyNonlinear.
Definition: nleq_err.hh:394
void setPreconFillLevel(int preconFillLevel_)
Sets the fillin-level of the preconditioner PrecondType::ILUK. The default fillin-level is 0.
Definition: nleq_err.hh:406
void setMonitorLevel(PrintLevel monitorLevel_)
Sets the monitor-output level. The default monitor-output level is none.
Definition: nleq_err.hh:451
void nleqErr(GridManager< Grid > &gridManager, Equation &eq, VariableSet const &variableSet, typename VariableSet::VariableSet *x, Spaces const &spaces, Timings &timer=Timings::instance())
Calls the nleqErr damped Newton-iteration solver.
Definition: nleq_err.hh:502
void setMaximumNoIterations(int maximumIter_)
Sets the maximum allowed number of Newton-iterations. The default value is 50.
Definition: nleq_err.hh:400
void setErrorStream(std::ostream &errorStream_)
Sets the error-output stream. The default error-output stream is std::cerr.
Definition: nleq_err.hh:430
void setRestricted(bool restricted_)
Sets the restricted monotonicity-test flag. The default value depends on the selected NonlinProblemTy...
Definition: nleq_err.hh:423
void setOutFilePrefix(const std::string &outFilePrefix_)
Sets the prefix of the output-files named <prefix>nnn.vtu, where n denotes a decimal digit....
Definition: nleq_err.hh:473
Supports gathering and reporting execution times information for nested program parts.
Definition: timing.hh:64
static Timings & instance()
Returns a reference to a single default instance.
A class for storing a heterogeneous collection of FunctionSpaceElement s.
Definition: variables.hh:341
VariableSet(Self const &vs)
Copy constructor.
Definition: variables.hh:362
A class for assembling Galerkin representation matrices and right hand sides for variational function...
Utility classes for the definition and use of variational functionals.
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Definition: fixdune.hh:110
Dune::FieldVector< T, n > min(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise minimum.
Definition: fixdune.hh:122
#define LAMBDA_START_EXTREMELY_DEFAULT
Definition: nleq_err.hh:353
#define SMALL
Definition: nleq_err.hh:272
#define LAMBDA_MIN_DEFAULT
Definition: nleq_err.hh:354
#define TOLMAX
#define LAMBDA_START_DEFAULT
Definition: nleq_err.hh:352
#define TOLMIN
#define MAX_ITER_DEFAULT
Definition: nleq_err.hh:351
#define LAMBDA_MIN_EXTREMELY_DEFAULT
Definition: nleq_err.hh:355
std::vector< double > * fx
Definition: nleq_err.hh:333
std::vector< double > * dx
Definition: nleq_err.hh:333
Output of mesh and solution for visualization software.