1#ifndef DUNE_FEM_SOLVER_RUNGEKUTTA_BASICROW_HH 
    2#define DUNE_FEM_SOLVER_RUNGEKUTTA_BASICROW_HH 
   18#include <dune/fem/solver/odesolver.hh> 
   19#include <dune/fem/solver/parameter.hh> 
   27  struct NoROWRungeKuttaSourceTerm
 
   30    bool operator() ( 
double time, 
double timeStepSize, 
int stage, 
const T &u, 
const std::vector< T * > &update, T &source )
 
   36    void limit( T& update, 
const double time ) {}
 
   39    double initialTimeStepEstimate ( 
double time, 
const T &u )
 const 
   45    double timeStepEstimate ()
 const 
   53  template< 
class HelmholtzOperator, 
class NonlinearSolver, 
class TimeStepControl, 
class SourceTerm = NoROWRungeKuttaSourceTerm >
 
   64    typedef HelmholtzOperator HelmholtzOperatorType;
 
   65    typedef NonlinearSolver NonlinearSolverType;
 
   66    typedef TimeStepControl TimeStepControlType;
 
   67    typedef SourceTerm SourceTermType;
 
   69    typedef typename NonlinearSolver::ParameterType                    NonlinearSolverParameterType;
 
   70    typedef typename NonlinearSolverType::LinearInverseOperatorType    LinearInverseOperatorType;
 
   72    typedef typename HelmholtzOperator::SpaceOperatorType::PreconditionOperatorType PreconditionOperatorType;
 
   83    template< 
class ButcherTable >
 
   86                               const ButcherTable &butcherTable,
 
   87                               const TimeStepControlType &timeStepControl,
 
   88                               const SourceTermType &sourceTerm,
 
   89                               const NonlinearSolverParameterType& parameter )
 
   90    : helmholtzOp_( helmholtzOp ),
 
   91      linearSolver_( parameter.linear() ),
 
   92      timeStepControl_( timeStepControl ),
 
   93      sourceTerm_( sourceTerm ),
 
   94      stages_( butcherTable.
stages() ),
 
   95      alpha_( butcherTable.A() ),
 
   96      alpha2_( butcherTable.B() ),
 
   99      c_( butcherTable.c() ),
 
  100      rhs_( 
"RK rhs", helmholtzOp_.space() ),
 
  101      temp_( 
"RK temp", helmholtzOp_.space() ),
 
  102      update_( 
stages(), nullptr ),
 
  103      maxLinearIterations_( parameter.linear().maxIterations() ),
 
  104      preconditioner_(helmholtzOp.spaceOperator().preconditioner())
 
  106      setup( butcherTable );
 
  109    template< 
class ButcherTable >
 
  111                               TimeProviderType& timeProvider,
 
  112                               const ButcherTable &butcherTable,
 
  113                               const TimeStepControlType &timeStepControl,
 
  114                               const SourceTermType &sourceTerm,
 
  115                               const Dune::Fem::ParameterReader ¶meter = Dune::Fem::Parameter::container() )
 
  116    : 
BasicROWRungeKuttaSolver( helmholtzOp, timeProvider, butcherTable, timeStepControl, sourceTerm, NonlinearSolverParameterType( parameter ) )
 
  125    template< 
class ButcherTable >
 
  128                               const ButcherTable &butcherTable,
 
  129                               const TimeStepControlType &timeStepControl,
 
  130                               const NonlinearSolverParameterType& parameter )
 
  134    template< 
class ButcherTable >
 
  136                               TimeProviderType& timeProvider,
 
  137                               const ButcherTable &butcherTable,
 
  138                               const TimeStepControlType &timeStepControl,
 
  139                               const Dune::Fem::ParameterReader ¶meter = Dune::Fem::Parameter::container() )
 
  140    : 
BasicROWRungeKuttaSolver( helmholtzOp, timeProvider, butcherTable, timeStepControl, SourceTermType(), NonlinearSolverParameterType( parameter ) )
 
  148    template< 
class ButcherTable >
 
  151                               const ButcherTable &butcherTable,
 
  152                               const NonlinearSolverParameterType& parameter )
 
  153    : 
BasicROWRungeKuttaSolver( helmholtzOp, timeProvider, butcherTable, TimeStepControlType(), SourceTermType(), parameter )
 
  156    template< 
class ButcherTable >
 
  158                               TimeProviderType& timeProvider,
 
  159                               const ButcherTable &butcherTable,
 
  160                               const Dune::Fem::ParameterReader ¶meter = Dune::Fem::Parameter::container() )
 
  161    : 
BasicROWRungeKuttaSolver( helmholtzOp, timeProvider, butcherTable, TimeStepControlType(), SourceTermType(), NonlinearSolverParameterType( parameter ) )
 
  164    template< 
class ButcherTable >
 
  165    void setup( 
const ButcherTable& butcherTable )
 
  169        std::cout << 
"ROW method of order=" << butcherTable.order() << 
" with " << stages_ << 
" stages" << std::endl;
 
  173      for( 
int i = 0; i < 
stages(); ++i )
 
  175        std::ostringstream name;
 
  176        name << 
"RK stage " << i;
 
  177        update_[ i ] = 
new DestinationType( name.str(), helmholtzOp_.space() );
 
  181      for( 
int i = 0; i < 
stages(); ++i )
 
  182        gamma_[ i ] = alpha_[ i ][ i ];
 
  185      alpha_.
mtv( butcherTable.b(), beta_ );
 
  192      for( 
int i = 0; i < 
stages(); ++i )
 
  199      const double time = timeStepControl_.time();
 
  201      helmholtzOp_.setTime( time );
 
  202      helmholtzOp_.initializeTimeStepSize( U0 );
 
  203      const double helmholtzEstimate = helmholtzOp_.timeStepEstimate();
 
  205      double sourceTermEstimate = sourceTerm_.initialTimeStepEstimate( time, U0 );
 
  207      if( sourceTermEstimate < 0.0 ) sourceTermEstimate = helmholtzEstimate ;
 
  209      timeStepControl_.initialTimeStepSize( helmholtzEstimate, sourceTermEstimate );
 
  215    void solve ( DestinationType &U, MonitorType &monitor )
 
  219      typename HelmholtzOperatorType::JacobianOperatorType jOp( 
"jacobianOperator", U.space(), U.space() );
 
  221      const double time = timeStepControl_.time();
 
  222      const double timeStepSize = timeStepControl_.timeStepSize();
 
  223      assert( timeStepSize > 0.0 );
 
  225      for( 
int s = 0; s < 
stages(); ++s )
 
  228        DestinationType& updateStage = *update_[ s ];
 
  231        for( 
int k = 0; k < s; ++k )
 
  232          rhs_.axpy( alpha2_[ s ][ k ], *update_[ k ] );
 
  233        helmholtzOp_.spaceOperator()(rhs_,updateStage);
 
  234        updateStage *= (gamma_[s]*timeStepSize);
 
  235        for( 
int k = 0; k < s; ++k )
 
  236          updateStage.axpy( -gamma_[s]*alpha_[ s ][ k ], *update_[ k ] );
 
  238        rhs_.assign( updateStage );
 
  241        const double stageTime = time + c_[ s ]*timeStepSize;
 
  242        helmholtzOp_.setTime( stageTime );
 
  247          helmholtzOp_.setLambda( gamma_[ s ]*timeStepSize );
 
  248          helmholtzOp_.jacobian( U, jOp );
 
  250        const int remLinearIts = maxLinearIterations_;
 
  252        linearSolver_.parameter().setMaxIterations( remLinearIts );
 
  255          linearSolver_.bind( jOp, *preconditioner_ );
 
  257          linearSolver_.bind( jOp );
 
  259        linearSolver_( rhs_, updateStage );
 
  260        monitor.linearSolverIterations_ += linearSolver_.iterations();
 
  262        linearSolver_.unbind();
 
  266      if(0 && timeStepControl_.computeError() )
 
  269        DestinationType Uerr( U );
 
  273        for( 
int s = 0; s < 
stages(); ++s )
 
  274          U.axpy( beta_[ s ], *update_[ s ] );
 
  277        Uerr.axpy( -1.0, U );
 
  278        const double errorU = Uerr.scalarProductDofs( Uerr );
 
  279        const double normU = U.scalarProductDofs( U );
 
  281        if( normU > 0 && errorU > 0 )
 
  283          error = std::sqrt( errorU / normU );
 
  285        std::cout << std::scientific << 
"Error in RK = " << error << 
" norm " << errorU << 
" " << normU << std::endl;
 
  291        for( 
int s = 0; s < 
stages(); ++s )
 
  292          U.axpy( beta_[ s ], *update_[ s ] );
 
  295      monitor.error_ = error;
 
  298      timeStepControl_.timeStepEstimate( helmholtzOp_.timeStepEstimate(), sourceTerm_.timeStepEstimate(), monitor );
 
  305      out << 
"Generic " << 
stages() << 
"-stage implicit Runge-Kutta solver.\\\\" << std::endl;
 
  310    double infNorm(
const DestinationType& U, 
const DestinationType& Uerr )
 const 
  312      typedef typename DestinationType :: ConstDofIteratorType ConstDofIteratorType ;
 
  313      const ConstDofIteratorType uend = U.dend();
 
  315      for( ConstDofIteratorType u = U.dbegin(), uerr = Uerr.dbegin(); u != uend; ++u, ++uerr )
 
  318        double uerrval = *uerr ;
 
  319        double div = std::abs( std::max( uval, uerrval ) );
 
  321        double norm = std::abs( uval - uerrval );
 
  322        if( std::abs(div) > 1e-12 )
 
  324        res = std::max( res, norm );
 
  329    HelmholtzOperatorType&     helmholtzOp_;
 
  330    LinearInverseOperatorType  linearSolver_;
 
  332    TimeStepControl timeStepControl_;
 
  333    SourceTerm sourceTerm_;
 
  340    DestinationType rhs_,temp_;
 
  341    std::vector< DestinationType * > update_;
 
  343    const int maxLinearIterations_;
 
  345    const PreconditionOperatorType *preconditioner_;
 
ROW RungeKutta ODE solver.
Definition: basicrow.hh:56
 
void solve(DestinationType &U, MonitorType &monitor)
solve the system
Definition: basicrow.hh:215
 
BasicROWRungeKuttaSolver(HelmholtzOperatorType &helmholtzOp, TimeProviderType &timeProvider, const ButcherTable &butcherTable, const TimeStepControlType &timeStepControl, const SourceTermType &sourceTerm, const NonlinearSolverParameterType ¶meter)
constructor
Definition: basicrow.hh:84
 
void description(std::ostream &out) const
print description of ODE solver to out stream
Definition: basicrow.hh:303
 
int stages() const
return stages of RK solver (-1 if not implemented)
Definition: basicrow.hh:301
 
void initialize(const DestinationType &U0)
apply operator once to get dt estimate
Definition: basicrow.hh:197
 
BasicROWRungeKuttaSolver(HelmholtzOperatorType &helmholtzOp, TimeProviderType &timeProvider, const ButcherTable &butcherTable, const NonlinearSolverParameterType ¶meter)
constructor
Definition: basicrow.hh:149
 
BasicROWRungeKuttaSolver(HelmholtzOperatorType &helmholtzOp, TimeProviderType &timeProvider, const ButcherTable &butcherTable, const TimeStepControlType &timeStepControl, const NonlinearSolverParameterType ¶meter)
constructor
Definition: basicrow.hh:126
 
~BasicROWRungeKuttaSolver()
destructor
Definition: basicrow.hh:190
 
Interface class for ODE Solver.
Definition: odesolverinterface.hh:21
 
Monitor MonitorType
monitor type
Definition: odesolverinterface.hh:59
 
virtual void solve(DestinationType &u)
solve  where  is the internal operator.
Definition: odesolverinterface.hh:75
 
DestinationImp DestinationType
type of destination
Definition: odesolverinterface.hh:62
 
void invert(bool doPivoting=true)
Compute inverse.
 
MAT & rightmultiply(const DenseMatrix< M2 > &M)
Multiplies M from the right to this matrix.
Definition: densematrix.hh:650
 
constexpr void mtv(const X &x, Y &y) const
y = A^T x
Definition: densematrix.hh:392
 
static bool verbose()
obtain the cached value for fem.verbose with default verbosity level 2
Definition: parameter.hh:466
 
general base for time providers
Definition: timeprovider.hh:36
 
This file implements a dense matrix with dynamic numbers of rows and columns.
 
This file implements a dense vector with a dynamic size.
 
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:485