287#define SMALL DBL_EPSILON
288#define EPMACH DBL_MIN
304 template<
class Gr
id,
class Equation,
class VariableSet,
class Spaces>
371 typedef enum {initial=1,intermediate=2,solution=3,
final=4} OutputMode;
374 std::vector<double> *fx, *dx;
375 int noIterationsForOrdinaryNewtonCorr, noIterationsForSimplifiedNewtonCorr,
376 maxNoGbitIterations, noCorrectorSteps;
378 double normF, normDx, normDxBar, lambda, theta,
379 toleranceForOrdinaryNewtonCorr, precisionOfOrdinaryNewtonCorr;
383 typedef typename Grid::LeafGridView LeafView;
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
401 maximumNoIterations = 50;
405 errorStream = &(std::cerr);
406 monitorStream = &(std::cout);
410 outFilePrefix =
"iter_";
411 scale =
new std::vector<double>(0);
527 void setOutFilePrefix(
const std::string& outFilePrefix_ ) { outFilePrefix=outFilePrefix_; }
536 if (scale_) scale=scale_;
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,
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;
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;
578 rhoTilde = 0.5*rho; rhoBarMaximum = rhoTilde/(1.0+rhoTilde);
579 struct NleqData *data =
new struct NleqData;
582 std::cerr << std::endl <<
" could not allocate struct data" << std::endl;
587 if ( monitorLevel > 0 )
588 *monitorStream << std::endl <<
" GiantGbit - Version 2.0" << std::endl;
608 if (data)
delete data;
612 LeafView leafGridView = gridManager.
grid().leafGridView();
614 Assembler assembler(spaces);
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));
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;
637 giantRescale(*scale,xData,w,xThresh);
638 if ( iterationCounter>0 )
640 normDxKminusOne = giantScaledNorm2(dxdata,*scale);
641 normDxBar = giantScaledNorm2(dxBar,*scale);
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);
652 for (
int j=0;j<n;j++) { w[j]=-(*fxk)[j]; dxdata[j]=dxBar[j]; };
653 dx.read(dxdata.begin());
657 iteEps = rho/(2.0*(1.0+rho));
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");
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);
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 )
684 hkpri = normDx/normDxKminusOne*hk;
685 lambda =
std::min(1.0,1.0/((1.0+rho)*hkpri));
687 if ( lambda == 1.0 && iterationCounter>0 )
690 iteEps = rho/2.0*hk/(1.0+hk);
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;
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));
710 noOrdinaryNewtonCorrIterations += noGbitIterations;
711 data->noIterationsForOrdinaryNewtonCorr = noGbitIterations;
712 data->toleranceForOrdinaryNewtonCorr = iteEps;
713 data->precisionOfOrdinaryNewtonCorr = res.precision;
716 if ( monitorLevel > 1 )
717 giantMonitor<LinearSolver>(iterationCounter,normDx,normOfFk,lambdaPrevious,iteEps,noGbitIterations,
' ',res);
718 if ( normDx <= xtol )
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++;
729 reducted =
false; data->noCorrectorSteps = -1;
731 bool doCorrectorLoop=
true;
734 data->noCorrectorSteps++; data->monviolated =
false;
735 if ( lambda < lambdaMin )
741 xkPlusOne=*x; xkPlusOne += tmp;
742 if (statistics) timer.start(
"time for assemble");
743 assembler.assemble(linearization(eq,xkPlusOne),assembler.RHS);
744 if (statistics) timer.stop(
"time for assemble");
746 CoefficientVectors fxq(assembler.rhs());
747 fxq.write(fxk->begin());
749 normOfFkplusOne = giantNorm2(*fxk);
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;
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) )
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);
781 data->monviolated =
true;
784 lambdaNew =
std::min(1.0,1.0/(hk*(1.0+rho)));
785 if ( lambda==1.0 && lambdaNew==1.0 )
787 if ( normDxBar <= xtol )
797 if( lambdaNew >= 4.0*lambda && !reducted )
799 lambda=lambdaNew;
continue;
802 doCorrectorLoop=
false;
804 while ( doCorrectorLoop );
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;
813 x->write(w.begin()); *x=xkPlusOne; x->write(xData.begin());
816 normOfFk = normOfFkplusOne;
818 while ( iterationCounter <= maximumNoIterations && info.
returnCode == 2 );
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");
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;
833 if ( (errorLevel > 0) && (info.
returnCode != 0) )
838 *errorStream << std::endl <<
839 " Error - Maximum allowed number of iterations exceeded" << std::endl;
842 *errorStream << std::endl <<
843 " Error - no convergence, damping factor became too small" << std::endl;
846 *errorStream << std::endl <<
847 " Error - no convergence of iterative linear solver for dx computation"
848 <<
" Gbit error code is " << subCode << std::endl;
851 *errorStream << std::endl <<
852 " Error - no convergence of iterative linear solver for dxq computation" <<
" Gbit error code is " << subCode << std::endl;
855 *errorStream << std::endl <<
" Error, code=" << info.
returnCode <<
856 ", subCode=" << fail << std::endl;
869 info.
noOrdLinIt = noOrdinaryNewtonCorrIterations;
870 info.
noSimLinIt = noSimplifiedNewtonCorrIterations;
871 info.
noMulJac = noJacobianVectorMultiplications;
872 info.
noPrecon = noPreconditionerCalls;
874 if (statistics) std::cout << timer << std::endl;
879 void giantRescale(std::vector<double>& scale, std::vector<double>
const & x,
880 std::vector<double>
const& xa, std::vector<double>
const& xThresh)
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++)
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)
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);
906 double giantScaledNorm2(std::vector<double>
const& v, std::vector<double>
const& scale)
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 );
915 double giantNorm2(std::vector<double>
const& v)
917 int const n=v.size();
919 for (
int i=0;i<n;i++) rval += v[i]*v[i];
920 return sqrt( rval / (
double)n );
923 void giantDataOut(
int const iterationCounter, LeafView
const leafGridView,
924 VariableSetRepresentation
const x,
struct NleqData
const *data)
926 if ( (dataLevel==
none) || ( (dataLevel==
minimum) && (data->mode==intermediate) ) )
931 std::ostringstream fname;
932 fname << outFilePrefix;
935 fname.setf(std::ios_base::right,std::ios_base::adjustfield);
936 fname << iterationCounter;
938 writeVTKFile(x,fname.str(),IoOptions());
941 int giantParcheckAndPrint(
int const n)
942 #define TOLMIN EPMACH*1.0e2
943 #define TOLMAX 1.0e-1
945 double large = 1.0/
SMALL, small =
SMALL, defaultScale;
949 *errorStream << std::endl <<
" Error - Number of Equations/unknowns must be >0" << std::endl;
955 *errorStream << std::endl <<
" Error - xtol must be positive" << std::endl;
964 *errorStream << std::endl <<
965 " User prescribed RTOL decreased to reasonable largest value RTOL=" <<
972 *errorStream << std::endl <<
973 "User prescribed RTOL increased to reasonable smallest value RTOL=" <<
982 if ( scale->empty() )
985 for (
int i=0;i<n;i++) (*scale)[i]=defaultScale;
989 for (
int i=0;i<n;i++)
991 if ( (*scale)[i] < 0.0 )
994 *errorStream << std::endl <<
995 " Error - negative value scale[" << i <<
"] supplied" << std::endl;
998 else if ( (*scale)[i] == 0.0 )
999 (*scale)[i] = defaultScale;
1000 else if ( (*scale)[i] <
SMALL )
1003 *errorStream << std::endl <<
1004 " Warning scale[" << i <<
"] too small - increased to " <<
SMALL << std::endl;
1005 (*scale)[i] = small;
1007 else if ( (*scale)[i] > large )
1010 *errorStream << std::endl <<
1011 " Warning scale[" << i <<
"] too large - decreased to " << large << std::endl;
1012 (*scale)[i] = large;
1016 if ( monitorLevel==0 )
return 0;
1017 *monitorStream << std::endl <<
" Problem dimension: n = " << n << std::endl;
1018 *monitorStream << std::endl <<
" Prescribed relative precision: " << xtol
1020 *monitorStream <<
" The problem is specified as being ";
1021 switch ( nonlinType )
1023 case mildlyNonlinear: *monitorStream <<
"mildly nonlinear" << std::endl;
1025 case highlyNonlinear: *monitorStream <<
"highly nonlinear" << std::endl;
1031 *monitorStream <<
" The restricted monotonicity test will be applied" << std::endl;
1033 *monitorStream <<
" The standard monotonicity test will be applied" << std::endl;
1035 *monitorStream <<
" The maximum permitted number of iteration steps is: " <<
1036 maximumNoIterations << std::endl;
1041 int maximumNoIterations, preconFillLevel;
1042 bool restricted, statistics;
1043 std::ostream *errorStream, *monitorStream;
1045 PrintLevel errorLevel, monitorLevel, dataLevel;
1047 std::vector<double>* scale;
1048 std::string outFilePrefix;
1049 struct NleqInfo info;
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....
Solution of a nonlinear system of equations by a damped Newton-method with adaptive precision control...
void setPreconFillLevel(int preconFillLevel_)
Sets the fillin-level of the preconditioner PrecondType::ILUK. The default fillin-level is 0.
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.
void setErrorLevel(PrintLevel errorLevel_)
Sets the error-output level. The default error-output level is verbose.
void setScalingVector(std::vector< double > *scale_)
Sets a user-defined scaling-threshold vector.
void setAdaptMode(AdaptMode adaptMode_)
Sets the adapt-mode (linear solver precision control). The default adapt-mode is standardMode.
void setSafetyFactor(double safetyFactor_)
Sets the safety factor for the precision control within the linear solver Gbit. The default value is ...
void setRestricted(bool restricted_)
Sets the restricted monotonicity-test flag. The default value depends on the selected NonlinProblemTy...
void setStatistics(bool statistics_)
Sets the Timings statistics flag. The default Timings statistics flag level is off.
void setTolerance(double tol_)
Sets the error tolerance which the final approximate solution must fit. The default value is 1....
void setMaximumNoIterations(int maximumIter_)
Sets the maximum allowed number of Newton-iterations. The default value is 50.
struct NleqInfo getInfo()
After calling giantGbit, getInfo returns the info structure contents.
void setErrorStream(std::ostream &errorStream_)
Sets the error-output stream. The default error-output stream is std::cerr.
void setNonlinProblemType(NonlinProblemType nonlinType_)
Set the classification of the nonlinear problem. The default value is highlyNonlinear.
void setOutFilePrefix(const std::string &outFilePrefix_)
Sets the prefix of the output-files named <prefix>nnn.vtu, where n denotes a decimal digit....
void setDataLevel(PrintLevel dataLevel_)
Sets the plot-data-output level. The default plot-data-output level is none.
void setMonitorLevel(PrintLevel monitorLevel_)
Sets the monitor-output level. The default monitor-output level is none.
void setMonitorStream(std::ostream &monitorStream_)
Sets the monitor-output stream. The default monitor-output stream is std::cout.
Grid const & grid() const
Returns a const reference on the owned grid.
Supports gathering and reporting execution times information for nested program parts.
static Timings & instance()
Returns a reference to a single default instance.
A class for storing a heterogeneous collection of FunctionSpaceElement s.
VariableSet(Self const &vs)
Copy constructor.
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
#define LAMBDA_MIN_DEFAULT
#define LAMBDA_START_DEFAULT
#define LAMBDA_MIN_EXTREMELY_DEFAULT
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Dune::FieldVector< T, n > min(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise minimum.
int noJacobianEvaluations
std::vector< double > * dx
std::vector< double > * fx
int noFunctionEvaluations
Output of mesh and solution for visualization software.