dune-fem 2.12-git
Loading...
Searching...
No Matches
basicimplicit.hh
Go to the documentation of this file.
1#ifndef DUNE_FEM_SOLVER_RUNGEKUTTA_BASICIMPLICIT_HH
2#define DUNE_FEM_SOLVER_RUNGEKUTTA_BASICIMPLICIT_HH
3
4//- system includes
5#include <cassert>
6#include <cmath>
7#include <limits>
8#include <sstream>
9#include <vector>
10
11//- dune-common includes
14
15//- dune-fem includes
17
18namespace DuneODE
19{
20
21 // NoImplicitRungeKuttaSourceTerm
22 // ------------------------------
23
25 {
26 template< class T >
27 bool operator() ( double time, double timeStepSize, int stage, const T &u, const std::vector< T * > &update, T &source )
28 {
29 return false;
30 }
31
32 template< class T >
33 void limit( T& update, const double time ) {}
34
35 template< class T >
36 double initialTimeStepEstimate ( double time, const T &u ) const
37 {
38 // return negative value to indicate that implicit time step should be used
39 return -1.0;
40 }
41
42 double timeStepEstimate () const
43 {
45 }
46 };
47
48
49
51 template< class HelmholtzOperator, class NonlinearSolver, class TimeStepControl, class SourceTerm = NoImplicitRungeKuttaSourceTerm >
53 : public OdeSolverInterface< typename HelmholtzOperator::DomainFunctionType >
54 {
57
58 public:
61
66
68
69 typedef typename TimeStepControlType::ParameterType ParameterType;
70 typedef typename NonlinearSolver::ParameterType NonlinearSolverParameterType;
71
79 template< class ButcherTable >
81 const ButcherTable &butcherTable,
84 const NonlinearSolverParameterType& parameters )
86 nonlinearSolver_( parameters ),
89 stages_( butcherTable.stages() ),
90 ord_( butcherTable.order() ),
91 alpha_( butcherTable.A() ),
92 gamma_( stages() ),
93 beta_( stages() ),
94 c_( butcherTable.c() ),
95 rhs_( "RK rhs", helmholtzOp_.space() ),
98 {
99 setup( butcherTable );
100 }
101
108 template< class ButcherTable >
110 const ButcherTable &butcherTable,
112 const NonlinearSolverParameterType& parameters )
114 nonlinearSolver_( parameters ),
116 stages_( butcherTable.stages() ),
117 ord_( butcherTable.order() ),
118 alpha_( butcherTable.A() ),
119 gamma_( stages() ),
120 beta_( stages() ),
121 c_( butcherTable.c() ),
122 rhs_( "RK rhs", helmholtzOp_.space() ),
125 {
126 setup( butcherTable );
127 }
128
129 template< class ButcherTable >
138
139 template< class ButcherTable >
147
148 template< class ButcherTable >
149 void setup( const ButcherTable& butcherTable )
150 {
151 update_.clear();
152 update_.resize( stages(), nullptr );
154
155 // create intermediate functions
156 for( int i = 0; i < stages(); ++i )
157 {
159 name << "RK stage " << i;
160 updateStorage_[ i ].reset( new DestinationType( name.str(), helmholtzOp_.space() ) );
161 update_[ i ] = updateStorage_[ i ].operator ->();
162 }
163
164 // compute coefficients
166 for( int i = 0; i < stages(); ++i )
167 {
168 gamma_[ i ] = AL[ i ][ i ];
169 AL[ i ][ i ] = 0.0;
170 }
171
172 alpha_.invert();
173 alpha_.mtv( butcherTable.b(), beta_ );
174
176 for( int i = 0; i < stages(); ++i )
177 alpha_[ i ][ i ] = gamma_[ i ];
178
179 for( int i = 0; i < stages(); ++i )
180 {
181 gamma_[ i ] = 1.0;
182 for( int j = 0; j < i; ++j )
183 gamma_[ i ] -= alpha_[ i ][ j ];
184 }
185
186 delta_ = 1.0;
187 for( int i = 0; i < stages(); ++i )
188 delta_ -= beta_[ i ];
189
190 }
191
194 {
195 const double time = timeStepControl_.time();
196
197 helmholtzOp_.setTime( time );
198 helmholtzOp_.initializeTimeStepSize( U0 );
199 const double helmholtzEstimate = helmholtzOp_.timeStepEstimate();
200
201 double sourceTermEstimate = sourceTerm_.initialTimeStepEstimate( time, U0 );
202 // negative time step is given by the empty source term
204
206 }
207
208 using BaseType::solve;
209
212 {
213 monitor.reset();
214
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 )
219 {
220 assert( update_[ s ] );
221 // update for stage s
223
224 // assemble rhs of nonlinear equation
226 updateStage *= gamma_[ s ];
227 for( int k = 0; k < s; ++k )
228 updateStage.axpy( alpha_[ s ][ k ], *update_[ k ] );
229
230 const double stageTime = time + c_[ s ]*timeStepSize;
231 if( sourceTerm_( time, timeStepSize, s, U, update_, rhs_ ) )
232 {
233 updateStage.axpy( alpha_[ s ][ s ]*timeStepSize, rhs_ );
235 }
236
237 // apply Helmholtz operator to right hand side
238 helmholtzOp_.setTime( stageTime );
239 helmholtzOp_.setLambda( 0 );
241
242 // solve the system
243 helmholtzOp_.setLambda( alpha_[ s ][ s ]*timeStepSize );
246 nonlinearSolver_.unbind();
247
248 // update monitor
249 monitor.newtonIterations_ += nonlinearSolver_.iterations();
250 monitor.linearSolverIterations_ += nonlinearSolver_.linearIterations();
251
252 // on failure break solving
253 if( !nonlinearSolver_.converged() )
254 return timeStepControl_.reduceTimeStep( helmholtzOp_.timeStepEstimate(), sourceTerm_.timeStepEstimate(), monitor );
255 }
256
257 double error = 0.0;
258 if( timeStepControl_.computeError() )
259 {
260 // store U (to be revised)
262
263 // update solution
264 U *= delta_;
265 for( int s = 0; s < stages(); ++s )
266 U.axpy( beta_[ s ], *update_[ s ] );
267
268 //error = infNorm( U, Uerr );
269 Uerr.axpy( -1.0, U );
270 const double errorU = Uerr.scalarProductDofs( Uerr );
271 const double normU = U.scalarProductDofs( U );
272
273 if( normU > 0 && errorU > 0 )
274 {
275 error = std::sqrt( errorU / normU );
276 }
277 std::cout << std::scientific << "Error in RK = " << error << " norm " << errorU << " " << normU << std::endl;
278 //std::cout << std::scientific << "Error in RK = " << error << std::endl;
279 }
280 else
281 {
282 // update solution
283 U *= delta_;
284 for( int s = 0; s < stages(); ++s )
285 U.axpy( beta_[ s ], *update_[ s ] );
286 }
287 // set error to monitor
288 monitor.error_ = error;
289
290 // update time step size
291 timeStepControl_.timeStepEstimate( helmholtzOp_.timeStepEstimate(), sourceTerm_.timeStepEstimate(), monitor );
292 }
293
294 int stages () const { return stages_; }
295
296 int order () const { return ord_; }
297
299 {
300 out << "Generic " << stages() << "-stage implicit Runge-Kutta solver.\\\\" << std::endl;
301 }
302
303 protected:
304 double infNorm(const DestinationType& U, const DestinationType& Uerr ) const
305 {
306 typedef typename DestinationType :: ConstDofIteratorType ConstDofIteratorType ;
307 const ConstDofIteratorType uend = U.dend();
308 double res = 0;
309 for( ConstDofIteratorType u = U.dbegin(), uerr = Uerr.dbegin(); u != uend; ++u, ++uerr )
310 {
311 double uval = *u;
312 double uerrval = *uerr ;
313 double div = std::abs( std::max( uval, uerrval ) );
314
315 double norm = std::abs( uval - uerrval );
316 if( std::abs(div) > 1e-12 )
317 norm /= div;
318 res = std::max( res, norm );
319 }
320 return res;
321 }
322
327
329 int ord_;
330
331 double delta_;
334
338 };
339
340} // namespace DuneODE
341
342#endif // #ifndef DUNE_FEM_SOLVER_RUNGEKUTTA_BASICIMPLICIT_HH
const char * name()
virtual void operator()()=0
Dune::Fem::Double abs(const Dune::Fem::Double &a)
Definition double.hh:942
Definition multistep.hh:17
void invert(bool doPivoting=true)
DynamicMatrix< K > & leftmultiply(const DenseMatrix< M2 > &M)
constexpr void mtv(const X &x, Y &y) const
constexpr derived_type & axpy(const field_type &a, const DenseVector< Other > &x)
static ParameterContainer & container()
Definition io/parameter.hh:199
Interface class for ODE Solver.
Definition odesolverinterface.hh:21
virtual void solve(DestinationType &u)
solve where is the internal operator.
Definition odesolverinterface.hh:75
DestinationImp DestinationType
type of destination
Definition odesolverinterface.hh:62
Definition odesolverinterface.hh:27
Definition basicimplicit.hh:25
void limit(T &update, const double time)
Definition basicimplicit.hh:33
double initialTimeStepEstimate(double time, const T &u) const
Definition basicimplicit.hh:36
double timeStepEstimate() const
Definition basicimplicit.hh:42
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
std::vector< std::unique_ptr< DestinationType > > updateStorage_
Definition basicimplicit.hh:336
BasicImplicitRungeKuttaSolver(HelmholtzOperatorType &helmholtzOp, const ButcherTable &butcherTable, const Dune::Fem::ParameterReader &parameter=Dune::Fem::Parameter::container())
Definition basicimplicit.hh:140
double delta_
Definition basicimplicit.hh:331
DestinationType rhs_
Definition basicimplicit.hh:335
NonlinearSolver::ParameterType NonlinearSolverParameterType
Definition basicimplicit.hh:70
Dune::Fem::TimeProviderBase TimeProviderType
Definition basicimplicit.hh:67
Dune::DynamicMatrix< double > alpha_
Definition basicimplicit.hh:332
double infNorm(const DestinationType &U, const DestinationType &Uerr) const
Definition basicimplicit.hh:304
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 &parameters)
constructor
Definition basicimplicit.hh:80
int stages_
Definition basicimplicit.hh:328
Dune::DynamicVector< double > beta_
Definition basicimplicit.hh:333
Dune::DynamicVector< double > gamma_
Definition basicimplicit.hh:333
BaseType::DestinationType DestinationType
Definition basicimplicit.hh:60
HelmholtzOperatorType & helmholtzOp_
Definition basicimplicit.hh:323
SourceTerm sourceTerm_
Definition basicimplicit.hh:326
void initialize(const DestinationType &U0)
apply operator once to get dt estimate
Definition basicimplicit.hh:193
NonlinearSolverType nonlinearSolver_
Definition basicimplicit.hh:324
SourceTerm SourceTermType
Definition basicimplicit.hh:65
TimeStepControl TimeStepControlType
Definition basicimplicit.hh:64
BaseType::MonitorType MonitorType
Definition basicimplicit.hh:59
int order() const
return order of RK solver (-1 if not implemented)
Definition basicimplicit.hh:296
Dune::DynamicVector< double > c_
Definition basicimplicit.hh:333
std::vector< DestinationType * > update_
Definition basicimplicit.hh:337
NonlinearSolver NonlinearSolverType
Definition basicimplicit.hh:63
TimeStepControlType::ParameterType ParameterType
Definition basicimplicit.hh:69
BasicImplicitRungeKuttaSolver(HelmholtzOperatorType &helmholtzOp, const ButcherTable &butcherTable, const TimeStepControlType &timeStepControl, const NonlinearSolverParameterType &parameters)
constructor
Definition basicimplicit.hh:109
int ord_
Definition basicimplicit.hh:329
BasicImplicitRungeKuttaSolver(HelmholtzOperatorType &helmholtzOp, const ButcherTable &butcherTable, const TimeStepControlType &timeStepControl, const Dune::Fem::ParameterReader &parameter=Dune::Fem::Parameter::container())
Definition basicimplicit.hh:130
void solve(DestinationType &U, MonitorType &monitor)
solve the system
Definition basicimplicit.hh:211
TimeStepControl timeStepControl_
Definition basicimplicit.hh:325
HelmholtzOperator HelmholtzOperatorType
Definition basicimplicit.hh:62
void setup(const ButcherTable &butcherTable)
Definition basicimplicit.hh:149
general base for time providers
Definition timeprovider.hh:36
T assign(T... args)
T clear(T... args)
T div(T... args)
T endl(T... args)
T scientific(T... args)
T forward(T... args)
T max(T... args)
T resize(T... args)
T sqrt(T... args)
T time(T... args)