209#include <dune/istl/operators.hh>
210#include <dune/istl/preconditioners.hh>
215#define SMALL DBL_EPSILON
216#define EPMACH DBL_MIN
229 template<
class LinearSpace>
232 #define TAU_MIN 1.0e-8
233 #define TAU_MAX 1.0e2
234 #define EPSILON_LIMIT 1.0e20
236 #define MAXITER_DEFAULT 1000
267 typedef enum { initial=1,intermediate=2,solution=3,
final=4 } DataMode ;
271 double tau, t, normDx;
277 typedef Dune::Preconditioner<LinearSpace,LinearSpace>
Precond;
296 tol(iteEps_), maximumNoIterations(iteSteps_), maxRestart(maxRestart_)
302 giantSimplifiedCorrection =
false;
305 errorStream = &(std::cerr);
306 monitorStream = &(std::cout);
308 delta.resize(maxRestart+2);
309 for (
int i=0;i<maxRestart+2;i++) delta[i]=NULL;
314 for (
int i=0;i<maxRestart+2;i++)
delete delta[i];
403 if ( scale )
delete scale;
404 if ( scale_ ) scale=scale_;
421 LinearSpace qDomain(y),qRange(y);
422 int i, iterationCounter=0, noMatVecMult=0, noPrecondCalls=0;
423 struct GbitData* data=
new struct GbitData;
426 fprintf(stderr,
"\n could not allocate struct data\n");
427 res.
rcode=-994;
return;
429 data->mode = initial;
430 res.
rcode = gbitParameterCheckAndPrint();
433 if (data) free(data);
436 for (
int i=0;i<maxRestart+2;i++)
437 if (!delta[i]) delta[i]=
new std::vector<double>(n);
438 std::vector<double> *zeta, *delta0, *deltaOfM, *deltaOfMplusOne, *deltai, *deltaip1;
439 std::vector<double> sigma(maxRestart+2), t(maxRestart+2), q(n), z(n), ythresh(n), y0(n),
441 double gamma, tau, factor, OneMinusTm, ti, epsilon, normOfyIterPlusOne, normdiff, errtol=tol;
443 if ( !errorStream && errorLevel>0 ) errorStream = &(std::cerr);
444 if ( !monitorStream && monitorLevel>0 ) monitorStream = &(std::cout);
446 if ( monitorLevel > 0 ) *monitorStream << std::endl <<
" GBIT - Version 2.0" << std::endl;
448 y.write(ydata.begin());
449 b.write(bdata.begin());
450 for (
int j=0;j<n;j++) y0[j]=ydata[j];
451 if ( monitorLevel > 1 )
452 *monitorStream << std::endl <<
" Iter sigma NormIter tau t" <<
453 std::endl << std::endl;
454 for (
int j=0;j<n;j++) ythresh[j] = (*scale)[j];
458 bool doRestart=
true, doRestartNow;
462 if (rescale) gbitRescale(*scale,ydata,ythresh);
463 if ( iterationCounter > 0 && monitorLevel > 1 ) *monitorStream <<
" > RESTART" << std::endl;
464 normOfyIterPlusOne = scaledNorm2(ydata,*scale);
465 if (statistics) timer.start(
"time for matrix times vector");
467 if (statistics) timer.stop(
"time for matrix times vector");
468 noMatVecMult++; qRange.write(z.begin());
469 for (
int j=0;j<n;j++) z[j] = bdata[j]-z[j];
470 qRange.read(z.begin());
471 if (statistics) timer.start(
"time for preconditioner");
472 precon->apply(qDomain,qRange);
473 if (statistics) timer.stop(
"time for preconditioner");
475 qDomain.write(delta0->begin());
476 sigma[0] = scaledScalarProduct(*(delta[0]),*(delta[0]),*scale);
479 stopIteration =
false;
480 for (i=0; i<maxRestart+1 && !stopIteration && iterationCounter < maximumNoIterations+1; i++)
482 qDomain.read(delta[i]->begin());
483 if (statistics) timer.start(
"time for matrix times vector");
484 a->apply(qDomain,qRange);
485 if (statistics) timer.stop(
"time for matrix times vector");
487 if (statistics) timer.start(
"time for preconditioner");
488 precon->apply(qDomain,qRange); noPrecondCalls++; qDomain.write(zeta->begin());
489 if (statistics) timer.stop(
"time for preconditioner");
490 for (
int m=0;m<i;m++)
492 OneMinusTm = 1.0-t[m];
493 factor = scaledScalarProduct(*(delta[m]),*zeta,*scale)/sigma[m];
494 deltaOfM = delta[m]; deltaOfMplusOne = delta[m+1];
495 for (
int j=0;j<n;j++) (*zeta)[j] += factor*((*deltaOfMplusOne)[j]-OneMinusTm*(*deltaOfM)[j]);
497 gamma = scaledScalarProduct(*(delta[i]),z,*scale);
498 if ( gamma != 0.0 ) tau = sigma[i]/gamma;
502 if ( monitorLevel > 1 ) *monitorStream <<
" > tau = " << tau << std::endl;
511 if ( monitorLevel > 0 )
512 *monitorStream <<
" > Restart condition ignored, set t[0] = " << t[i] << std::endl;
522 ti = t[i]; deltai = delta[i];
523 if ( monitorLevel > 1 )
524 *monitorStream <<
" " << std::setw(4) << iterationCounter <<
" " << std::setw(11)
525 << sigma[i] <<
" " << std::setw(11) << normOfyIterPlusOne <<
" "
526 << std::setw(11) << tau <<
" " << std::setw(11)
527 << t[i] << std::endl;
528 data->normDx = sqrt(sigma[i]); data->tau = tau; data->t = t[i];
530 data->mode = intermediate;
531 for (
int j=0;j<n;j++) ydata[j] += ti*(*deltai)[j];
532 y.read(ydata.begin());
533 deltaip1 = delta[i+1];
535 for (
int j=0;j<n;j++) (*deltaip1)[j] = factor*(*deltai)[j]-tau*z[j];
536 sigma[i+1] = scaledScalarProduct(*deltaip1,*deltaip1,*scale);
537 if ( i>=1 ) epsilon = 0.5*sqrt(sigma[i-1]+2.0*sigma[i]+sigma[i+1]);
538 else epsilon = sqrt(sigma[1]);
539 normOfyIterPlusOne = scaledNorm2(ydata,*scale);
540 if (giantSimplifiedCorrection)
542 for (
int j=0;j<n;j++) q[j]=ydata[j]-y0[j];
543 normdiff = scaledNorm2(q,*scale);
544 stopIteration = (epsilon/normdiff < rho*errtol);
547 stopIteration = (epsilon < rho*normOfyIterPlusOne*errtol);
551 res.
rcode = 3;
break;
554 if ( res.
rcode != 0 )
break;
555 if ( doRestartNow || ( i>=maxRestart && !stopIteration && iterationCounter<maximumNoIterations) )
560 while ( doRestart ) ;
561 if ( (res.
rcode==0) && (iterationCounter >= maximumNoIterations) ) res.
rcode = 2;
563 if ( monitorLevel > 1 )
564 *monitorStream <<
" " << std::setw(4) << iterationCounter <<
" " << std::setw(11)
565 << sigma[i] <<
" " << std::setw(11) << normOfyIterPlusOne <<
" "
566 << std::setw(11) << tau <<
" " << std::setw(11)
567 << t[i-1] << std::endl;
568 data->mode = ( res.
rcode==0 ? solution : final );
569 data->normDx = sqrt(sigma[i]); data->tau = tau; data->t = t[i-1];
571 if ( errorLevel > 0 && res.
rcode != 0 )
576 *errorStream <<
"\n Error - Maximum allowed number of iterations exceeded\n" ;
579 *errorStream <<
"\n Error - no convergence, correction too large\n" ;
582 *errorStream <<
"\n Error, code=" << res.
rcode << std::endl;
586 res.
precision = epsilon/(rho*normOfyIterPlusOne);
587 res.
normDx = data->normDx;
595 void gbitRescale(std::vector<double>& scale, std::vector<double>
const& y,
596 std::vector<double>
const& ythresh)
598 int const n = scale.size();
599 assert ( (y.size()==n) && (ythresh.size()==n) );
600 for (
int i=0;i<n;i++)
604 int gbitParameterCheckAndPrint()
605 #define TOLMIN 1.0e-15
608 double large = 1.0/
SMALL, default_scale;
612 *errorStream <<
"\n Error - Number of Equations/unknowns must be >0\n" ;
618 *errorStream <<
"\n Error - tol must be positive\n" ;
628 "\n User prescribed RTOL decreased to reasonable largest value RTOL=" <<
636 "\n User prescribed RTOL increased to reasonable smallest value RTOL=" <<
643 scale =
new std::vector<double>(n);
644 for (
int i=0;i<n;i++) (*scale)[i]=default_scale;
648 for (
int i=0;i<n;i++)
650 if ( (*scale)[i] < 0.0 )
654 "\n Error - negative value (*scale)[" << i <<
"] supplied\n";
657 else if ( (*scale)[i] == 0.0 )
658 (*scale)[i] = default_scale;
659 else if ( (*scale)[i] <
SMALL )
663 "\n Warning: (*scale)[" << i <<
"] too small - increased to "<<
SMALL <<
"\n";
666 else if ( (*scale)[i] > large )
670 "\n Warning: (*scale)[" << i <<
"] too large - decreased to %" << large <<
"\n";
676 if ( maxRestart <= 0 )
679 if ( errorLevel > 1 )
681 " Warning: maxRestart not set; is reset to maxRestart=" << maxRestart << std::endl;
683 else if ( maxRestart > n )
686 if ( errorLevel > 1 )
688 " Warning: maxRestart is greater than n; is reset to maxRestart=" << maxRestart << std::endl;
694 if ( errorLevel > 1 )
696 " Warning: rho not set; is reset to rho=" << rho << std::endl;
699 if ( monitorLevel==0 )
return 0;
700 *monitorStream <<
"\n Problem dimension: n = " << n << std::endl;
701 *monitorStream <<
"\n Prescribed relative precision: " << tol << std::endl;
702 *monitorStream <<
" The maximum permitted number of iteration steps is: " <<
703 maximumNoIterations << std::endl;
704 *monitorStream <<
" The maximum number of iterations before restart is: " <<
705 maxRestart << std::endl;
706 *monitorStream <<
" The safety factor is rho = " << rho << std::endl;
710 double scaledNorm2(std::vector<double>
const& v,std::vector<double>
const& scale)
712 int const n=scale.size();
713 assert( v.size()==n );
714 double t, rval = 0.0;
715 for (
int i=0;i<n;i++) {t=v[i]/scale[i]; rval += t*t;};
716 return sqrt( rval / (
double)n );
719 double scaledScalarProduct( std::vector<double>
const& v1, std::vector<double>
const& v2,
720 std::vector<double>
const& scale)
722 int const n=scale.size();
723 assert( (v1.size()==n) && (v2.size()==n) );
724 double t1, t2, rval = 0.0;
725 for (
int i=0;i<n;i++)
726 {t1=v1[i]/scale[i]; t2=v2[i]/scale[i]; rval += t1*t2;};
727 return rval / (double)n ;
732 std::vector<std::vector<double>*> delta;
733 std::vector<double>* scale;
734 int maxRestart, maximumNoIterations;
735 bool rescale, giantSimplifiedCorrection, statistics;
736 PrintLevel errorLevel, monitorLevel, dataLevel;
737 std::ostream *errorStream, *monitorStream;
Iterative solution of a large linear system using an error based termination-criterium....
void setRescaleMode(bool rescale_)
Sets the rescaling mode. The default value is true.
void setMonitorLevel(PrintLevel monitorLevel_)
Sets the monitor-output level. The default monitor-output level is the value of the constructur argum...
void setSafetyFactor(double safetyFactor_)
Sets the safety factor for the precision control. Must be a positive number <= 1.0 by which the toler...
void setGiantSimpleTermination(bool giantSimple_)
Sets the termination-criterium mode. The default value is false.
Gbit(AssembledGalerkinOperator &a_, Precond &precon_, double iteEps_=1.0e-10, int iteSteps_=MAXITER_DEFAULT, int verbosity_=0, int maxRestart_=9)
The Gbit constructor routine.
void setErrorLevel(PrintLevel errorLevel_)
Sets the error-output level. The default error-output level is verbose.
void setTolerance(double tol_)
Sets the error tolerance which the final approximate solution must fit. The default value is 1....
void setErrorStream(std::ostream &errorStream_)
Sets the error-output stream. The default error-output stream is std::cerr.
void setStatistics(bool statistics_)
Sets the Timings statistics flag. The default Timings statistics flag level is off.
Dune::Preconditioner< LinearSpace, LinearSpace > Precond
Dune::LinearOperator< LinearSpace, LinearSpace > AssembledGalerkinOperator
void setScalingVector(std::vector< double > *scale_)
Sets a user-defined scaling-threshold vector.
void apply(LinearSpace &y, LinearSpace const &b, struct GbitInfo &res, Timings &timer=Timings::instance())
Calls the giantGbit inexact damped Newton-iteration solver.
void setMaximumNoIterations(int maximumIter_)
Sets the maximum allowed number of Newton-iterations. The default value is the value of the construct...
void setMonitorStream(std::ostream &monitorStream_)
Sets the monitor-output stream. The default monitor-output stream is std::cout.
Supports gathering and reporting execution times information for nested program parts.
static Timings & instance()
Returns a reference to a single default instance.
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.