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 );
301 int stages ()
const {
return stages_; }
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
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.
void mtv(const X &x, Y &y) const
y = A^T x
Definition: densematrix.hh:387
MAT & rightmultiply(const DenseMatrix< M2 > &M)
Multiplies M from the right to this matrix.
Definition: densematrix.hh:645
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:484