1#ifndef DUNE_FEM_SOLVER_RUNGEKUTTA_BASICIMPLICIT_HH
2#define DUNE_FEM_SOLVER_RUNGEKUTTA_BASICIMPLICIT_HH
16#include <dune/fem/solver/odesolverinterface.hh>
24 struct NoImplicitRungeKuttaSourceTerm
27 bool operator() (
double time,
double timeStepSize,
int stage,
const T &u,
const std::vector< T * > &update, T &source )
33 void limit( T& update,
const double time ) {}
36 double initialTimeStepEstimate (
double time,
const T &u )
const
42 double timeStepEstimate ()
const
51 template<
class HelmholtzOperator,
class NonlinearSolver,
class TimeStepControl,
class SourceTerm = NoImplicitRungeKuttaSourceTerm >
62 typedef HelmholtzOperator HelmholtzOperatorType;
63 typedef NonlinearSolver NonlinearSolverType;
64 typedef TimeStepControl TimeStepControlType;
65 typedef SourceTerm SourceTermType;
69 typedef typename TimeStepControlType::ParameterType ParameterType;
70 typedef typename NonlinearSolver::ParameterType NonlinearSolverParameterType;
79 template<
class ButcherTable >
81 const ButcherTable &butcherTable,
82 const TimeStepControlType &timeStepControl,
83 const SourceTermType &sourceTerm,
84 const NonlinearSolverParameterType& parameters )
85 : helmholtzOp_( helmholtzOp ),
86 nonlinearSolver_( parameters ),
87 timeStepControl_( timeStepControl ),
88 sourceTerm_( sourceTerm ),
89 stages_( butcherTable.
stages() ),
90 ord_( butcherTable.
order() ),
91 alpha_( butcherTable.A() ),
94 c_( butcherTable.c() ),
95 rhs_(
"RK rhs", helmholtzOp_.space() ),
97 update_(
stages(), nullptr )
99 setup( butcherTable );
108 template<
class ButcherTable >
110 const ButcherTable &butcherTable,
111 const TimeStepControlType &timeStepControl,
112 const NonlinearSolverParameterType& parameters )
113 : helmholtzOp_( helmholtzOp ),
114 nonlinearSolver_( parameters ),
115 timeStepControl_( timeStepControl ),
116 stages_( butcherTable.
stages() ),
117 ord_( butcherTable.
order() ),
118 alpha_( butcherTable.A() ),
121 c_( butcherTable.c() ),
122 rhs_(
"RK rhs", helmholtzOp_.space() ),
124 update_(
stages(), nullptr )
126 setup( butcherTable );
129 template<
class ButcherTable >
131 const ButcherTable &butcherTable,
132 const TimeStepControlType &timeStepControl,
133 const Dune::Fem::ParameterReader ¶meter = Dune::Fem::Parameter::container() )
135 NonlinearSolverParameterType( parameter ) )
139 template<
class ButcherTable >
141 const ButcherTable &butcherTable,
142 const Dune::Fem::ParameterReader ¶meter = Dune::Fem::Parameter::container() )
144 TimeStepControlType( parameter ), NonlinearSolverParameterType( parameter ) )
148 template<
class ButcherTable >
149 void setup(
const ButcherTable& butcherTable )
152 update_.resize(
stages(),
nullptr );
153 updateStorage_.resize(
stages() );
156 for(
int i = 0; i <
stages(); ++i )
158 std::ostringstream name;
159 name <<
"RK stage " << i;
160 updateStorage_[ i ].reset(
new DestinationType( name.str(), helmholtzOp_.space() ) );
161 update_[ i ] = updateStorage_[ i ].operator ->();
166 for(
int i = 0; i <
stages(); ++i )
168 gamma_[ i ] = AL[ i ][ i ];
173 alpha_.
mtv( butcherTable.b(), beta_ );
176 for(
int i = 0; i <
stages(); ++i )
177 alpha_[ i ][ i ] = gamma_[ i ];
179 for(
int i = 0; i <
stages(); ++i )
182 for(
int j = 0; j < i; ++j )
183 gamma_[ i ] -= alpha_[ i ][ j ];
187 for(
int i = 0; i <
stages(); ++i )
188 delta_ -= beta_[ i ];
195 const double time = timeStepControl_.time();
197 helmholtzOp_.setTime( time );
198 helmholtzOp_.initializeTimeStepSize( U0 );
199 const double helmholtzEstimate = helmholtzOp_.timeStepEstimate();
201 double sourceTermEstimate = sourceTerm_.initialTimeStepEstimate( time, U0 );
203 if( sourceTermEstimate < 0.0 ) sourceTermEstimate = helmholtzEstimate ;
205 timeStepControl_.initialTimeStepSize( helmholtzEstimate, sourceTermEstimate );
211 void solve ( DestinationType &U, MonitorType &monitor )
215 const double time = timeStepControl_.time();
216 const double timeStepSize = timeStepControl_.timeStepSize();
217 assert( timeStepSize > 0.0 );
218 for(
int s = 0; s <
stages(); ++s )
220 assert( update_[ s ] );
222 DestinationType& updateStage = *update_[ s ];
225 updateStage.assign( U );
226 updateStage *= gamma_[ s ];
227 for(
int k = 0; k < s; ++k )
228 updateStage.
axpy( alpha_[ s ][ k ], *update_[ k ] );
230 const double stageTime = time + c_[ s ]*timeStepSize;
231 if( sourceTerm_( time, timeStepSize, s, U, update_, rhs_ ) )
233 updateStage.
axpy( alpha_[ s ][ s ]*timeStepSize, rhs_ );
234 sourceTerm_.limit( updateStage, stageTime );
238 helmholtzOp_.setTime( stageTime );
239 helmholtzOp_.setLambda( 0 );
240 helmholtzOp_( updateStage, rhs_ );
243 helmholtzOp_.setLambda( alpha_[ s ][ s ]*timeStepSize );
244 nonlinearSolver_.bind( helmholtzOp_ );
245 nonlinearSolver_( rhs_, updateStage );
246 nonlinearSolver_.unbind();
249 monitor.newtonIterations_ += nonlinearSolver_.iterations();
250 monitor.linearSolverIterations_ += nonlinearSolver_.linearIterations();
253 if( !nonlinearSolver_.converged() )
254 return timeStepControl_.reduceTimeStep( helmholtzOp_.timeStepEstimate(), sourceTerm_.timeStepEstimate(), monitor );
258 if( timeStepControl_.computeError() )
261 DestinationType Uerr( U );
265 for(
int s = 0; s <
stages(); ++s )
266 U.axpy( beta_[ s ], *update_[ s ] );
269 Uerr.axpy( -1.0, U );
270 const double errorU = Uerr.scalarProductDofs( Uerr );
271 const double normU = U.scalarProductDofs( U );
273 if( normU > 0 && errorU > 0 )
275 error = std::sqrt( errorU / normU );
277 std::cout << std::scientific <<
"Error in RK = " << error <<
" norm " << errorU <<
" " << normU << std::endl;
284 for(
int s = 0; s <
stages(); ++s )
285 U.axpy( beta_[ s ], *update_[ s ] );
288 monitor.error_ = error;
291 timeStepControl_.timeStepEstimate( helmholtzOp_.timeStepEstimate(), sourceTerm_.timeStepEstimate(), monitor );
300 out <<
"Generic " <<
stages() <<
"-stage implicit Runge-Kutta solver.\\\\" << std::endl;
304 double infNorm(
const DestinationType& U,
const DestinationType& Uerr )
const
306 typedef typename DestinationType :: ConstDofIteratorType ConstDofIteratorType ;
307 const ConstDofIteratorType uend = U.dend();
309 for( ConstDofIteratorType u = U.dbegin(), uerr = Uerr.dbegin(); u != uend; ++u, ++uerr )
312 double uerrval = *uerr ;
313 double div = std::abs( std::max( uval, uerrval ) );
315 double norm = std::abs( uval - uerrval );
316 if( std::abs(div) > 1e-12 )
318 res = std::max( res, norm );
323 HelmholtzOperatorType& helmholtzOp_;
324 NonlinearSolverType nonlinearSolver_;
325 TimeStepControl timeStepControl_;
326 SourceTerm sourceTerm_;
335 DestinationType rhs_;
336 std::vector< std::unique_ptr< DestinationType > > updateStorage_;
337 std::vector< DestinationType* > update_;
Implicit RungeKutta ODE solver.
Definition: basicimplicit.hh:54
void description(std::ostream &out) const
print description of ODE solver to out stream
Definition: basicimplicit.hh:298
int stages() const
return stages of RK solver (-1 if not implemented)
Definition: basicimplicit.hh:294
BasicImplicitRungeKuttaSolver(HelmholtzOperatorType &helmholtzOp, const ButcherTable &butcherTable, const TimeStepControlType &timeStepControl, const SourceTermType &sourceTerm, const NonlinearSolverParameterType ¶meters)
constructor
Definition: basicimplicit.hh:80
void initialize(const DestinationType &U0)
apply operator once to get dt estimate
Definition: basicimplicit.hh:193
int order() const
return order of RK solver (-1 if not implemented)
Definition: basicimplicit.hh:296
BasicImplicitRungeKuttaSolver(HelmholtzOperatorType &helmholtzOp, const ButcherTable &butcherTable, const TimeStepControlType &timeStepControl, const NonlinearSolverParameterType ¶meters)
constructor
Definition: basicimplicit.hh:109
void solve(DestinationType &U, MonitorType &monitor)
solve the system
Definition: basicimplicit.hh:211
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 & leftmultiply(const DenseMatrix< M2 > &M)
Multiplies M from the left to this matrix.
Definition: densematrix.hh:632
constexpr void mtv(const X &x, Y &y) const
y = A^T x
Definition: densematrix.hh:392
constexpr derived_type & axpy(const field_type &a, const DenseVector< Other > &x)
vector space axpy operation ( *this += a x )
Definition: densevector.hh:590
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:489