KASKADE 7 development version
giant_gbit.hh
Go to the documentation of this file.
1/*
2 giantGbit - Error-based Inexact Damped Newton algorithm with linear solver Gbit.
3
4 * Written by L. Weimann
5 * Purpose solution of systems of nonlinear equations
6 * Method Inexact 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 giantGbit starts up with dampingfactor=1.
77 highlyNonlinear: The problem is considered to be highly nonlinear and
78 giantGbit starts up with dampingfactor=1.0e-4.
79 extremelyNonlinear: The problem is considered to be extremely nonlinear
80 and giantGbit 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 setAdaptMode( AdaptMode adaptMode )
106 adaptMode controls the strategy how to set the prescribed precision for
107 the Gbit iteration.
108 Valid AdaptMode values are standardMode and quadraticMode.
109
110 void setErrorStream( std::ostream& errorStream )
111 errorStream is of type pointer to std::ostream, as defined by the <iostream>
112 header file. It must be set either to a NULL pointer, std::cout, std::cerr,
113 or to another file pointer which has been initialized by a fopen call.
114 If it is set to NULL, errorStream will be set to std:cerr. The error
115 messages will be printed to errorStream.
116
117 void setMonitorStream( std::ostream& monitorStream )
118 monitorStream is of type pointer to std::ostream, as defined by the <iostream>
119 header file. It must be set either to a NULL pointer, std::cout, std::cerr,
120 or to another file pointer which has been initialized by a fopen call.
121 If it is set to NULL, monitorStream will be set to std::cout. The monitor
122 output will be printed to monitorStream.
123
124 void setErrorLevel( PrintLevel errorLevel )
125 errorLevel is of type PrintLevel. If it is set to level none,
126 then no error message will be printed if an error condition occurs.
127 If it is set to level minimum or any higher level, then error messages
128 will be printed, if appropriate.
129
130 void setMonitorLevel( PrintLevel monitorLevel )
131 monitorLevel is of type PrintLevel. If it is set to level none,
132 then no monitor output will be printed.
133 If it is set to level minimum, a few infomation will be printed.
134 If set to level verbose, then some infomation about each Newton iteration
135 step, fitting into a single line, will be printed. The higher level debug
136 is reserved for future additional information output.
137
138 void setDataLevel( PrintLevel dataLevel )
139 dataLevel is of type PrintLevel.
140 If it is set to level none, then no data output will be done.
141 If it is set to level minimum, the initial values and the final
142 values of the iteration vector x will be output to a file named
143 "<outFilePrefix>nnn.vtu" in vtu-format.
144 If it is set to level verbose or any higher level, then each Newton iterate
145 x will be output to a file named "<outFilePrefix>nnn.vtu" in vtu-format.
146
147 void setOutFilePrefix( const std::string& outFilePrefix )
148 outFilePrefix is a filename prefix used for the .vtu output file
149 for each iterate. The complete filename for the k-th iterate output
150 is outFilePrefinnn.vtu, where nnn is the value of k filled with leading
151 zeros for k<100.
152
153 void setScalingVector( std::vector<double>* scale )
154 scale is of type pointer to a std::vector<double> of size n.
155 *scale must, if scale is not the NULL pointer, contain positive scaling
156 values, which are used in computations of scaled norms, as follows:
157 || x || = squareroot(sum(1 to n) ( x_i/scale_i )^2)
158 The pointer may be initialized with a NULL pointer. In this case, all
159 scaling values are internally set to a default value, which depends on
160 the value of nonlinType.
161
162 struct NleqInfo getInfo()
163 returns some info about the Newton iteration and final Newton correction
164 and residuum vector.
165 In detail:
166 info.precision is of type double and is set to the achieved scaled norm
167 of the error of the final iterate.
168
169 info.normDx is of type double and is set to the unscaled norm of the
170 last Newton correction.
171
172 info.fx is a pointer to a double array of size n, which contains the
173 final residuum vector.
174
175 info.noIterations is set to number of Newton iteration steps done.
176
177 info.noFunctionEvaluations is set to the number of done evaluations of the right-
178 hand side of the linearized system.
179
180 info.noJacobianEvaluations is set to the number of computations of the Jacobian
181 of the linearized system.
182
183 info.noOrdLinIt is set to the number of done linear solver iteration steps
184 for computing ordinary Newton-corrections.
185
186 info.noSimLinIt is set to the number of done linear solver iteration steps for computing
187 simplified Newton-corrections.
188
189 info.noMulJac is set to the number of done Jacobian times vector multiplications
190 within the linear solver calls.
191
192 info.noPrecon is set to the number of done preconditioner calls within
193 the linear solver calls.
194
195 info.returnCode is set to the return-code of nleq_err. A return-code 0
196 means that nleq_err has terminated sucessfully. For the meaning of a
197 nonzero return-code, see the error messages list below.
198
199 info.subCode is set for certain failure conditions to the error code
200 which has been returned by a routine called from nleq_err.
201
202 The following error conditions may occur: (returned via info.returnCode)
203 --------------------------------------------------------------------
204
205 1 Singular Jacobian matrix (not yet realized),
206 giantGbit cannot proceed the iteration.
207 2 Maximum number of Newton iteration (as set by maximumNoIterations) exceeded.
208 3 No convergence of Newton iteration, damping factor became too small.
209 4 Linear solver Gbit failed to converge when computing
210 the ordinary Newton-correction.
211 5 Linear solver Gbit failed to converge when computing
212 the simplified Newton-correction.
213 21 Nonpositive value for xtol supplied.
214 22 Negative scaling value for some component of vector *scale
215 supplied.
216
217 void giantGbit(GridManager<Grid>& gridManager,
218 Equation& eq,
219 VariableSet const& variableSet,
220 typename VariableSet::VariableSet* x,
221 Spaces const& spaces)
222
223 A short description of the parameters of giantGbit follows:
224
225 GridManager<Grid>& gridManager:
226 The grid obtained by discretization (see Kaskade7 documentation).
227
228 Equation& eq:
229 The structure eq defining the Weak-formulation equation and boundary
230 conditions mainly by the class-menbers DomainCache::d1, DomainCache::d2,
231 BoundaryCache::d1 and BoundaryCache::d2. For details, consult the
232 Kaskade7 documentation.
233
234 VariableSet const& variableSet:
235 For details, consult the Kaskade7 documentation.
236
237 VariableSet::VariableSet* x:
238 x must contain on input an initial guess of the problems solution,
239 which is used as the start-vector of the damped Newton iteration.
240 On output, the pointed array contains an approximate solution vector x^k,
241 which fits the error condition
242 || x^k - x* || <= xtol,
243 where x* denotes the exact solution, and ||...|| is a scaled
244 Euclidian norm.
245 For the class member VariableSet::VariableSet, consult the Kaskade7
246 documentation.
247
248 Spaces const& spaces:
249 For details, consult the Kaskade7 documentation.
250
251 Summary of changes:
252 -------------------
253
254 Version Date Changes
255 2.0 2014/03/27 Special version for use with Kaskade7.2
256 1.1.1 2006/06/06 Missing int return code in function
257 nleqErrInitScale, bug fixed.
258 1.1 2006/06/02 Added the output data files iterfile, resfile and
259 miscfile, where optional data output is provided,
260 a single line, starting with the iteration number,
261 for each iteration step.
262 1.0 2006/05/30 initial release.
263
264*/
265
266#ifndef GIANTGBIT_HH
267#define GIANTGBIT_HH
268
269#include <cstdlib>
270#include <iostream>
271#include <vector>
272#include <cmath>
273#include <algorithm>
274#include <cassert>
275
276#include "fem/assemble.hh"
277#include "fem/istlinterface.hh"
278#include "fem/functional_aux.hh"
279#include "fem/gridmanager.hh"
280#include "linalg/iluprecond.hh"
281#include "linalg/gbit.hh"
282#include "io/vtk.hh"
283#include "utilities/timing.hh"
284
285#ifndef MACHCONST_
286#define MACHCONST_
287#define SMALL DBL_EPSILON
288#define EPMACH DBL_MIN
289#endif
290
291namespace Kaskade
292{
304 template<class Grid, class Equation, class VariableSet, class Spaces>
305 class Giant
306 {
307 public:
308 typedef enum {
312 debug=3
313 }
314 PrintLevel ;
319 typedef enum {
329 typedef enum {
332 }
333 AdaptMode;
362 struct NleqInfo
363 {
365 std::vector<double> *fx, *dx;
368 };
369
370 private:
371 typedef enum {initial=1,intermediate=2,solution=3,final=4} OutputMode;
372 struct NleqData
373 {
374 std::vector<double> *fx, *dx;
375 int noIterationsForOrdinaryNewtonCorr, noIterationsForSimplifiedNewtonCorr,
376 maxNoGbitIterations, noCorrectorSteps;
377 bool monviolated;
378 double normF, normDx, normDxBar, lambda, theta,
379 toleranceForOrdinaryNewtonCorr, precisionOfOrdinaryNewtonCorr;
380 OutputMode mode;
381 };
382
383 typedef typename Grid::LeafGridView LeafView;
384 typedef typename VariableSet::VariableSet VariableSetRepresentation;
385
386 #define THETA_MAX 0.5
387 #define MAX_ITER_DEFAULT 50
388 #define LAMBDA_START_DEFAULT 1.0e-2
389 #define LAMBDA_START_EXTREMELY_DEFAULT 1.0e-4
390 #define LAMBDA_MIN_DEFAULT 1.0e-4
391 #define LAMBDA_MIN_EXTREMELY_DEFAULT 1.0e-8
392 #define DELTA_BAR 1.0e-3
393
394 public:
395
397 {
398 xtol = 1.0e-5;
399 rho=0.25;
400 nonlinType = highlyNonlinear;
401 maximumNoIterations = 50;
402 restricted = false;
403 preconFillLevel=0;
404 adaptMode = standardMode;
405 errorStream = &(std::cerr);
406 monitorStream = &(std::cout);
407 errorLevel = verbose;
408 monitorLevel = none;
409 dataLevel = none;
410 outFilePrefix = "iter_";
411 scale = new std::vector<double>(0);
412 statistics=false;
413 }
414
420 void setTolerance( double tol_ ) { xtol=tol_; }
421
434 void setNonlinProblemType(NonlinProblemType nonlinType_ ) { nonlinType=nonlinType_; }
435
441 void setSafetyFactor( double safetyFactor_ ) { rho=safetyFactor_; }
442
447 void setMaximumNoIterations( int maximumIter_ ) { maximumNoIterations=maximumIter_; }
448
453 void setPreconFillLevel( int preconFillLevel_ ) { preconFillLevel=preconFillLevel_; }
454
470 void setRestricted( bool restricted_ ) { restricted=restricted_; }
471
478 void setAdaptMode( AdaptMode adaptMode_ ) { adaptMode=adaptMode_; }
479
485 void setErrorStream( std::ostream& errorStream_ ) { errorStream=&errorStream_; }
486
492 void setMonitorStream( std::ostream& monitorStream_ ) { monitorStream=&monitorStream_; }
493
499 void setErrorLevel( PrintLevel errorLevel_ ) { errorLevel=errorLevel_; }
500
506 void setMonitorLevel( PrintLevel monitorLevel_ ) { monitorLevel=monitorLevel_; }
507
513 void setDataLevel( PrintLevel dataLevel_ ) { dataLevel=dataLevel_; }
514
520 void setStatistics( bool statistics_ ) { statistics=statistics_; }
527 void setOutFilePrefix( const std::string& outFilePrefix_ ) { outFilePrefix=outFilePrefix_; }
528
533 void setScalingVector( std::vector<double>* scale_ )
534 {
535 delete scale;
536 if (scale_) scale=scale_;
537 }
538
542 struct NleqInfo getInfo() { return info; }
543
556 void giantGbit(GridManager<Grid>& gridManager,
557 Equation& eq,
558 VariableSet const& variableSet,
559 typename VariableSet::VariableSet* x,
560 Spaces const& spaces, Timings& timer=Timings::instance())
561 {
562 int const neq = Equation::TestVars::noOfVariables;
563 int const nvars = Equation::AnsatzVars::noOfVariables;
564 typedef typename VariableSet::template CoefficientVectorRepresentation<0,neq>::type CoefficientVectors;
565 double lambda, lambdaNew, lambdaPrevious, hk, normOfFk, normOfFkplusOne, normDxKminusOne,
566 normDxBar, normOfDifference, normDx, theta, s, hkpri,
567 lambdaMin, rhoBar, rhoTilde, rhoBarMaximum, iteEps,
568 safetyFactor=rho;
569 int const n = variableSet.degreesOfFreedom(0,nvars);
570 int iterationCounter=0, fail=0, noGbitIterations, noOrdinaryNewtonCorrIterations=0,
571 noSimplifiedNewtonCorrIterations=0, noJacobianVectorMultiplications=0,
572 noPreconditionerCalls=0, subCode;
573 bool reducted;
574 std::vector<double> dxdata(n), dxBar(n), xThresh(n), w(n), xData(n);
575 std::vector<double> *fxk = new std::vector<double>(n);
576 int noRHSComputations=0, noJacobianComputations=0;
577 int iteSteps = 1000;
578 rhoTilde = 0.5*rho; rhoBarMaximum = rhoTilde/(1.0+rhoTilde);
579 struct NleqData *data = new struct NleqData;
580 if (!data)
581 {
582 std::cerr << std::endl << " could not allocate struct data" << std::endl;
583 info.returnCode=-994; return;
584 };
585 data->theta = 0.0;
586
587 if ( monitorLevel > 0 )
588 *monitorStream << std::endl << " GiantGbit - Version 2.0" << std::endl;
589 if ( maximumNoIterations <= 0 ) maximumNoIterations = MAX_ITER_DEFAULT;
590 if ( nonlinType==mildlyNonlinear )
591 {
592 lambda = 1.0; lambdaMin = LAMBDA_MIN_DEFAULT;
593 }
594 else if ( nonlinType==highlyNonlinear )
595 {
596 lambda = LAMBDA_START_DEFAULT; lambdaMin = LAMBDA_MIN_DEFAULT;
597 }
598 else if ( nonlinType==extremelyNonlinear )
599 {
602 restricted = true;
603 };
604
605 info.returnCode = giantParcheckAndPrint(n);
606 if ( info.returnCode !=0 )
607 {
608 if (data) delete data;
609 return;
610 };
611
612 LeafView leafGridView = gridManager.grid().leafGridView();
614 Assembler assembler(spaces);
615 typename VariableSet::VariableSet dx(variableSet);
616 typename VariableSet::VariableSet tmp(variableSet);
617 typename VariableSet::VariableSet xkPlusOne(variableSet);
618 size_t nnz = assembler.nnz(0,neq,0,nvars,false);
619 if ( monitorLevel > 0 )
620 *monitorStream << " nvars=" << nvars << ", neq=" << neq << ", nnz=" << nnz << "\n";
621 CoefficientVectors theSolution(VariableSet::template CoefficientVectorRepresentation<0,neq>::init(spaces));
623
624 x->write(xData.begin());
625 if ( monitorLevel > 1 )
626 *monitorStream << std::endl
627 << " iter normScl(dx) norm(fk) tolPrescr precision itlin lambda"
628 << std::endl << std::endl;
629 normDx = 0.0; normDxBar = 0.0;
630 w=xData; xThresh=*scale;
631 data->noIterationsForSimplifiedNewtonCorr = 0;
632 data->maxNoGbitIterations = iteSteps;
633 info.returnCode = 2;
634
635 do
636 {
637 giantRescale(*scale,xData,w,xThresh);
638 if ( iterationCounter>0 ) // recompute norms after rescaling
639 {
640 normDxKminusOne = giantScaledNorm2(dxdata,*scale);
641 normDxBar = giantScaledNorm2(dxBar,*scale);
642 };
643 if (statistics) timer.start("time for assemble");
644 assembler.assemble(linearization(eq,*x));
645 if (statistics) timer.stop("time for assemble");
646 noRHSComputations++; noJacobianComputations++;
647 CoefficientVectors fx(assembler.rhs());
648 fx.write(fxk->begin());
649 normOfFk = giantNorm2(*fxk);
651
652 for (int j=0;j<n;j++) { w[j]=-(*fxk)[j]; dxdata[j]=dxBar[j]; };
653 dx.read(dxdata.begin());
654 if ( adaptMode == quadraticMode )
655 iteEps = 0.25;
656 else
657 iteEps = rho/(2.0*(1.0+rho));
658
659 typedef typename VariableSet::template CoefficientVectorRepresentation<0,neq>::type LinearSpace;
660 if (statistics) timer.start("time for preconditioner setup");
662 if (statistics) timer.stop("time for preconditioner setup");
663 typedef Gbit<LinearSpace> LinearSolver;
664 struct LinearSolver::GbitInfo res;
665 LinearSolver gbit(A,iluk);
666 gbit.setTolerance(iteEps);
667 gbit.setSafetyFactor(rho);
668 gbit.setMaximumNoIterations(iteSteps);
669 gbit.setGiantSimpleTermination(false);
670 gbit.setStatistics(statistics);
671 theSolution = 0;
672 if (statistics) timer.start("time for linear solver gbit");
673 gbit.apply(theSolution,fx,res,timer);
674 if (statistics) timer.stop("time for linear solver gbit");
675 noGbitIterations = res.iterationCount;
676 noJacobianVectorMultiplications += res.noMatVecMult; noPreconditionerCalls += res.noPrecondCalls;
677 if ( res.rcode !=0 ) { info.returnCode=4; subCode= res.rcode; break; };
678 dx.data = theSolution.data;
679 dx.write(dxdata.begin());
680 normDx = giantScaledNorm2(dxdata,*scale);
681 lambdaPrevious = lambda;
682 if ( iterationCounter>0 )
683 {
684 hkpri = normDx/normDxKminusOne*hk;
685 lambda = std::min(1.0,1.0/((1.0+rho)*hkpri));
686 };
687 if ( lambda == 1.0 && iterationCounter>0 )
688 {
689 if ( adaptMode == quadraticMode )
690 iteEps = rho/2.0*hk/(1.0+hk);
691 else
692 iteEps = DELTA_BAR;
693 gbit.setTolerance(iteEps);
694 if (statistics) timer.start("time for linear solver gbit");
695 gbit.apply(theSolution,fx,res,timer);
696 if (statistics) timer.stop("time for linear solver gbit");
697 noGbitIterations += res.iterationCount;
698 noJacobianVectorMultiplications += res.noMatVecMult;
699 noPreconditionerCalls += res.noPrecondCalls;
700 if ( res.rcode !=0 )
701 {
702 info.returnCode=4; subCode= res.rcode; break;
703 };
704 dx.data = theSolution.data;
705 dx.write(dxdata.begin());
706 normDx = giantScaledNorm2(dxdata,*scale);
707 hkpri = normDx/normDxKminusOne*hk;
708 lambda = std::min(1.0,1.0/((1.0+rho)*hkpri));
709 };
710 noOrdinaryNewtonCorrIterations += noGbitIterations;
711 data->noIterationsForOrdinaryNewtonCorr = noGbitIterations;
712 data->toleranceForOrdinaryNewtonCorr = iteEps;
713 data->precisionOfOrdinaryNewtonCorr = res.precision;
714 hk = hkpri;
715
716 if ( monitorLevel > 1 )
717 giantMonitor<LinearSolver>(iterationCounter,normDx,normOfFk,lambdaPrevious,iteEps,noGbitIterations,' ',res);
718 if ( normDx <= xtol ) /* solution found, if condition is true */
719 {
720 data->normF = normOfFk; data->normDx = normDx;
721 data->normDxBar = normDxBar; data->lambda = lambda;
722 if (statistics) timer.start("time for writing output data");
723 giantDataOut(iterationCounter,leafGridView,*x,data);
724 if (statistics) timer.stop("time for writing output data");
725 *x += dx; iterationCounter++;
726 info.precision = normDx;
727 info.returnCode=0; break;
728 };
729 reducted = false; data->noCorrectorSteps = -1;
730
731 bool doCorrectorLoop=true;
732 do
733 {
734 data->noCorrectorSteps++; data->monviolated = false;
735 if ( lambda < lambdaMin )
736 {
737 info.returnCode=3; break; // stop, convergence failure!
738 };
739 tmp = dx;
740 tmp *= -lambda;
741 xkPlusOne=*x; xkPlusOne += tmp; /* new trial iterate */
742 if (statistics) timer.start("time for assemble");
743 assembler.assemble(linearization(eq,xkPlusOne),assembler.RHS);
744 if (statistics) timer.stop("time for assemble");
745 noRHSComputations++;
746 CoefficientVectors fxq(assembler.rhs());
747 fxq.write(fxk->begin());
748
749 normOfFkplusOne = giantNorm2(*fxk);
750 s = 1.0-lambda;
751 for (int j=0;j<n;j++) { w[j]=-(*fxk)[j]; dxBar[j]=s*dxdata[j]; };
752 gbit.setTolerance(rhoBarMaximum);
753 gbit.setGiantSimpleTermination(true);
754 theSolution.read(dxBar.begin());
755 if (statistics) timer.start("time for linear solver gbit");
756 gbit.apply(theSolution,fxq,res,timer);
757 if (statistics) timer.stop("time for linear solver gbit");
758 if ( res.rcode !=0 ) { info.returnCode=5; subCode= res.rcode; break; };
759 noSimplifiedNewtonCorrIterations += res.iterationCount;
760 data->noIterationsForSimplifiedNewtonCorr = res.iterationCount;
761 noJacobianVectorMultiplications += res.noMatVecMult;
762 noPreconditionerCalls += res.noPrecondCalls;
763 theSolution.write(dxBar.begin());
764 normDxBar = giantScaledNorm2(dxBar,*scale);
765 if ( monitorLevel > 1 )
766 giantMonitor<LinearSolver>(iterationCounter,normDxBar,normOfFkplusOne,
767 lambda,rhoBarMaximum,res.iterationCount,'*',res);
768 theta = normDxBar/normDx;
769 s = 1.0-lambda;
770 for (int i=0;i<n;i++) w[i] = dxBar[i]-s*dxdata[i];
771 normOfDifference = giantScaledNorm2(w,*scale);
772 rhoBar = res.precision*safetyFactor*normDxBar/normOfDifference;
773 hk = 2.0*(1.0-rhoBar)*normOfDifference/(lambda*lambda*normDx);
774 if ( ( !restricted && theta >= 1.0 ) ||
775 ( restricted && theta > 1.0-lambda/4.0) )
776 {
777 lambdaNew = std::min(1.0/(hk*(1.0+rho)),0.5*lambda);
778 if ( lambda <= lambdaMin ) lambda = lambdaNew;
779 else lambda = std::max(lambdaNew,lambdaMin);
780 reducted = true;
781 data->monviolated = true;
782 continue;
783 };
784 lambdaNew = std::min(1.0,1.0/(hk*(1.0+rho)));
785 if ( lambda==1.0 && lambdaNew==1.0 )
786 {
787 if ( normDxBar <= xtol )
788 {
789 *x += tmp;
790 info.precision = normDxBar;
791 info.returnCode=0;
792 break;
793 };
794 }
795 else
796 {
797 if( lambdaNew >= 4.0*lambda && !reducted )
798 {
799 lambda=lambdaNew; continue;
800 };
801 };
802 doCorrectorLoop=false;
803 }
804 while ( doCorrectorLoop );
805 if ( info.returnCode !=2 ) break;
806 data->normF = normOfFk; data->normDx = normDx;
807 data->normDxBar = normDxBar; data->lambda = lambda;
808 if (statistics) timer.start("time for writing output data");
809 giantDataOut(iterationCounter,leafGridView,*x,data);
810 if (statistics) timer.stop("time for writing output data");
811 data->mode = intermediate;
812 // save previous iterate for scaling purposes and accept new iterate
813 x->write(w.begin()); *x=xkPlusOne; x->write(xData.begin());
814 // next step
815 iterationCounter++;
816 normOfFk = normOfFkplusOne;
817 }
818 while ( iterationCounter <= maximumNoIterations && info.returnCode == 2 );
819
820 data->normF = normOfFkplusOne; data->normDx = normDx;
821 data->normDxBar = normDxBar; data->lambda = lambda;
822 data->mode = ( info.returnCode==0 ? solution : final );
823 if (statistics) timer.start("time for writing output data");
824 giantDataOut(iterationCounter,leafGridView,*x,data);
825 if (statistics) timer.stop("time for writing output data");
826
827 if ( (monitorLevel > 0) && (info.returnCode==0) )
828 *monitorStream << std::endl <<
829 " solution of nonlinear system obtained within " << iterationCounter << " Newton iteration steps" <<
830 std::endl << " using " << noJacobianComputations << " Jacobian assemblies and " << noRHSComputations <<
831 " function assemblies" << std::endl;
832
833 if ( (errorLevel > 0) && (info.returnCode != 0) )
834 {
835 switch ( info.returnCode )
836 {
837 case 2:
838 *errorStream << std::endl <<
839 " Error - Maximum allowed number of iterations exceeded" << std::endl;
840 break;
841 case 3:
842 *errorStream << std::endl <<
843 " Error - no convergence, damping factor became too small" << std::endl;
844 break;
845 case 4:
846 *errorStream << std::endl <<
847 " Error - no convergence of iterative linear solver for dx computation"
848 << " Gbit error code is " << subCode << std::endl;
849 break;
850 case 5:
851 *errorStream << std::endl <<
852 " Error - no convergence of iterative linear solver for dxq computation" << " Gbit error code is " << subCode << std::endl;
853 break;
854 default :
855 *errorStream << std::endl << " Error, code=" << info.returnCode <<
856 ", subCode=" << fail << std::endl;
857 };
858 };
859 info.subCode = fail;
860 delete data;
861
862 info.precision = normDx;
863 info.normDx = normDx;
864
865 // store info
866 info.noIterations = iterationCounter;
867 info.noFunctionEvaluations = noRHSComputations;
868 info.noJacobianEvaluations = noJacobianComputations;
869 info.noOrdLinIt = noOrdinaryNewtonCorrIterations;
870 info.noSimLinIt = noSimplifiedNewtonCorrIterations;
871 info.noMulJac = noJacobianVectorMultiplications;
872 info.noPrecon = noPreconditionerCalls;
873 info.fx = fxk;
874 if (statistics) std::cout << timer << std::endl;
875 }
876
877 private:
878
879 void giantRescale(std::vector<double>& scale, std::vector<double> const & x,
880 std::vector<double> const& xa, std::vector<double> const& xThresh)
881 {
882 int const n=scale.size();
883 assert ( (x.size()==n) && (xa.size()==n) && (xThresh.size()==n) );
884 for (int i=0;i<n;i++)
885 scale[i] = std::max(xThresh[i],std::max(0.5*(std::abs(x[i])+std::abs(xa[i])),SMALL));
886 }
887
888 template <class LinearSolver>
889 void giantMonitor(int const iterationCounter, double const normDx,
890 double const normF, double const lambda, double const tolLinIter,
891 int const noLinIter, char const indicator,
892 struct LinearSolver::GbitInfo res)
893 {
894 *monitorStream << " " << std::setw(4) << iterationCounter << " " << std::setw(1) << indicator << " "
895 << std::setw(12) << std::setprecision(5) << std::scientific << normDx << " "
896 << std::setw(12) << std::setprecision(5) << normF << " ";
897 *monitorStream << std::setw(9) << std::setprecision(2) << tolLinIter << " "
898 << std::setw(9) << std::setprecision(2) << res.precision << " ";
899 monitorStream->unsetf(std::ios::fixed | std::ios::scientific);
900 *monitorStream << std::setw(4) << noLinIter << " "
901 << std::setw(11) << std::setprecision(8) << std::fixed
902 << lambda << std::endl;
903 monitorStream->unsetf(std::ios::fixed | std::ios::scientific);
904 }
905
906 double giantScaledNorm2(std::vector<double> const& v, std::vector<double> const& scale)
907 {
908 int const n=v.size();
909 assert ( scale.size()==n );
910 double t, rval = 0.0;
911 for (int i=0;i<n;i++) {t=v[i]/scale[i]; rval += t*t;};
912 return sqrt( rval / (double)n );
913 }
914
915 double giantNorm2(std::vector<double> const& v)
916 {
917 int const n=v.size();
918 double rval = 0.0;
919 for (int i=0;i<n;i++) rval += v[i]*v[i];
920 return sqrt( rval / (double)n );
921 }
922
923 void giantDataOut(int const iterationCounter, LeafView const leafGridView,
924 VariableSetRepresentation const x, struct NleqData const *data)
925 {
926 if ( (dataLevel==none) || ( (dataLevel==minimum) && (data->mode==intermediate) ) )
927 return;
928 // output of solution in VTK format for visualization,
929 // the data are written as ascii stream into file temperature.vtu,
930 // possible is also binary
931 std::ostringstream fname;
932 fname << outFilePrefix;
933 fname.width(3);
934 fname.fill('0');
935 fname.setf(std::ios_base::right,std::ios_base::adjustfield);
936 fname << iterationCounter;
937 fname.flush();
938 writeVTKFile(x,fname.str(),IoOptions());
939 }
940
941 int giantParcheckAndPrint(int const n)
942 #define TOLMIN EPMACH*1.0e2
943 #define TOLMAX 1.0e-1
944 {
945 double large = 1.0/SMALL, small = SMALL, defaultScale;
946 if ( n<=0 )
947 {
948 if ( errorLevel>0 )
949 *errorStream << std::endl << " Error - Number of Equations/unknowns must be >0" << std::endl;
950 return 20;
951 };
952 if ( xtol <= 0 )
953 {
954 if ( errorLevel>0 )
955 *errorStream << std::endl << " Error - xtol must be positive" << std::endl;
956 return 21;
957 }
958 else
959 {
960 if ( xtol > TOLMAX )
961 {
962 xtol = TOLMAX;
963 if ( errorLevel>1 )
964 *errorStream << std::endl <<
965 " User prescribed RTOL decreased to reasonable largest value RTOL=" <<
966 xtol << std::endl;
967 }
968 else if ( xtol < TOLMIN )
969 {
970 xtol = TOLMIN;
971 if ( errorLevel>1 )
972 *errorStream << std::endl <<
973 "User prescribed RTOL increased to reasonable smallest value RTOL=" <<
974 xtol << std::endl;
975 };
976 };
977 if ( nonlinType >= highlyNonlinear )
978 defaultScale = xtol;
979 else
980 defaultScale = 1.0;
981
982 if ( scale->empty() )
983 {
984 scale->resize(n);
985 for (int i=0;i<n;i++) (*scale)[i]=defaultScale;
986 }
987 else
988 {
989 for (int i=0;i<n;i++)
990 {
991 if ( (*scale)[i] < 0.0 )
992 {
993 if ( errorLevel>0 )
994 *errorStream << std::endl <<
995 " Error - negative value scale[" << i << "] supplied" << std::endl;
996 return 22;
997 }
998 else if ( (*scale)[i] == 0.0 )
999 (*scale)[i] = defaultScale;
1000 else if ( (*scale)[i] < SMALL )
1001 {
1002 if ( errorLevel>1 )
1003 *errorStream << std::endl <<
1004 " Warning scale[" << i << "] too small - increased to " << SMALL << std::endl;
1005 (*scale)[i] = small;
1006 }
1007 else if ( (*scale)[i] > large )
1008 {
1009 if ( errorLevel>1 )
1010 *errorStream << std::endl <<
1011 " Warning scale[" << i << "] too large - decreased to " << large << std::endl;
1012 (*scale)[i] = large;
1013 };
1014 };
1015 };
1016 if ( monitorLevel==0 ) return 0;
1017 *monitorStream << std::endl << " Problem dimension: n = " << n << std::endl;
1018 *monitorStream << std::endl << " Prescribed relative precision: " << xtol
1019 << std::endl;
1020 *monitorStream << " The problem is specified as being ";
1021 switch ( nonlinType )
1022 {
1023 case mildlyNonlinear: *monitorStream << "mildly nonlinear" << std::endl;
1024 break;
1025 case highlyNonlinear: *monitorStream << "highly nonlinear" << std::endl;
1026 break;
1027 case extremelyNonlinear: *monitorStream << "extremely nonlinear" << std::endl;
1028 break;
1029 };
1030 if ( restricted )
1031 *monitorStream << " The restricted monotonicity test will be applied" << std::endl;
1032 else
1033 *monitorStream << " The standard monotonicity test will be applied" << std::endl;
1034
1035 *monitorStream << " The maximum permitted number of iteration steps is: " <<
1036 maximumNoIterations << std::endl;
1037 return 0;
1038 }
1039
1040 double xtol, rho;
1041 int maximumNoIterations, preconFillLevel;
1042 bool restricted, statistics;
1043 std::ostream *errorStream, *monitorStream;
1044 AdaptMode adaptMode;
1045 PrintLevel errorLevel, monitorLevel, dataLevel;
1046 NonlinProblemType nonlinType;
1047 std::vector<double>* scale;
1048 std::string outFilePrefix;
1049 struct NleqInfo info;
1050
1051 };
1052}
1053#endif
An adaptor presenting a Dune::LinearOperator <domain_type,range_type> interface to a contiguous sub-b...
Iterative solution of a large linear system using an error based termination-criterium....
Definition: gbit.hh:231
Solution of a nonlinear system of equations by a damped Newton-method with adaptive precision control...
Definition: giant_gbit.hh:306
void setPreconFillLevel(int preconFillLevel_)
Sets the fillin-level of the preconditioner PrecondType::ILUK. The default fillin-level is 0.
Definition: giant_gbit.hh:453
void giantGbit(GridManager< Grid > &gridManager, Equation &eq, VariableSet const &variableSet, typename VariableSet::VariableSet *x, Spaces const &spaces, Timings &timer=Timings::instance())
Calls the giantGbit inexact damped Newton-iteration solver.
Definition: giant_gbit.hh:556
void setErrorLevel(PrintLevel errorLevel_)
Sets the error-output level. The default error-output level is verbose.
Definition: giant_gbit.hh:499
void setScalingVector(std::vector< double > *scale_)
Sets a user-defined scaling-threshold vector.
Definition: giant_gbit.hh:533
void setAdaptMode(AdaptMode adaptMode_)
Sets the adapt-mode (linear solver precision control). The default adapt-mode is standardMode.
Definition: giant_gbit.hh:478
void setSafetyFactor(double safetyFactor_)
Sets the safety factor for the precision control within the linear solver Gbit. The default value is ...
Definition: giant_gbit.hh:441
void setRestricted(bool restricted_)
Sets the restricted monotonicity-test flag. The default value depends on the selected NonlinProblemTy...
Definition: giant_gbit.hh:470
void setStatistics(bool statistics_)
Sets the Timings statistics flag. The default Timings statistics flag level is off.
Definition: giant_gbit.hh:520
void setTolerance(double tol_)
Sets the error tolerance which the final approximate solution must fit. The default value is 1....
Definition: giant_gbit.hh:420
void setMaximumNoIterations(int maximumIter_)
Sets the maximum allowed number of Newton-iterations. The default value is 50.
Definition: giant_gbit.hh:447
struct NleqInfo getInfo()
After calling giantGbit, getInfo returns the info structure contents.
Definition: giant_gbit.hh:542
void setErrorStream(std::ostream &errorStream_)
Sets the error-output stream. The default error-output stream is std::cerr.
Definition: giant_gbit.hh:485
void setNonlinProblemType(NonlinProblemType nonlinType_)
Set the classification of the nonlinear problem. The default value is highlyNonlinear.
Definition: giant_gbit.hh:434
void setOutFilePrefix(const std::string &outFilePrefix_)
Sets the prefix of the output-files named <prefix>nnn.vtu, where n denotes a decimal digit....
Definition: giant_gbit.hh:527
void setDataLevel(PrintLevel dataLevel_)
Sets the plot-data-output level. The default plot-data-output level is none.
Definition: giant_gbit.hh:513
void setMonitorLevel(PrintLevel monitorLevel_)
Sets the monitor-output level. The default monitor-output level is none.
Definition: giant_gbit.hh:506
void setMonitorStream(std::ostream &monitorStream_)
Sets the monitor-output stream. The default monitor-output stream is std::cout.
Definition: giant_gbit.hh:492
Grid const & grid() const
Returns a const reference on the owned grid.
Definition: gridmanager.hh:292
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.
#define LAMBDA_START_EXTREMELY_DEFAULT
Definition: giant_gbit.hh:389
#define SMALL
Definition: giant_gbit.hh:287
#define DELTA_BAR
Definition: giant_gbit.hh:392
#define LAMBDA_MIN_DEFAULT
Definition: giant_gbit.hh:390
#define TOLMAX
#define LAMBDA_START_DEFAULT
Definition: giant_gbit.hh:388
#define TOLMIN
#define MAX_ITER_DEFAULT
Definition: giant_gbit.hh:387
#define LAMBDA_MIN_EXTREMELY_DEFAULT
Definition: giant_gbit.hh:391
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
std::vector< double > * dx
Definition: giant_gbit.hh:365
std::vector< double > * fx
Definition: giant_gbit.hh:365
Output of mesh and solution for visualization software.