DUNE-FEM (unstable)

basicrow.hh
1#ifndef DUNE_FEM_SOLVER_RUNGEKUTTA_BASICROW_HH
2#define DUNE_FEM_SOLVER_RUNGEKUTTA_BASICROW_HH
3
4//- system includes
5#include <algorithm>
6#include <cmath>
7#include <cassert>
8#include <limits>
9#include <sstream>
10#include <string>
11#include <vector>
12
13//- dune-common includes
16
17//- dune-fem includes
18#include <dune/fem/solver/odesolver.hh>
19#include <dune/fem/solver/parameter.hh>
20
21namespace DuneODE
22{
23
24 // NoROWRungeKuttaSourceTerm
25 // ------------------------------
26
27 struct NoROWRungeKuttaSourceTerm
28 {
29 template< class T >
30 bool operator() ( double time, double timeStepSize, int stage, const T &u, const std::vector< T * > &update, T &source )
31 {
32 return false;
33 }
34
35 template< class T >
36 void limit( T& update, const double time ) {}
37
38 template< class T >
39 double initialTimeStepEstimate ( double time, const T &u ) const
40 {
41 // return negative value to indicate that implicit time step should be used
42 return -1.0;
43 }
44
45 double timeStepEstimate () const
46 {
48 }
49
50 };
51
53 template< class HelmholtzOperator, class NonlinearSolver, class TimeStepControl, class SourceTerm = NoROWRungeKuttaSourceTerm >
55 : public OdeSolverInterface< typename HelmholtzOperator::DomainFunctionType >
56 {
59
60 public:
61 typedef typename BaseType::MonitorType MonitorType;
62 typedef typename BaseType::DestinationType DestinationType;
63
64 typedef HelmholtzOperator HelmholtzOperatorType;
65 typedef NonlinearSolver NonlinearSolverType;
66 typedef TimeStepControl TimeStepControlType;
67 typedef SourceTerm SourceTermType;
68
69 typedef typename NonlinearSolver::ParameterType NonlinearSolverParameterType;
70 typedef typename NonlinearSolverType::LinearInverseOperatorType LinearInverseOperatorType;
71
72 typedef typename HelmholtzOperator::SpaceOperatorType::PreconditionOperatorType PreconditionOperatorType;
73
75
83 template< class ButcherTable >
84 BasicROWRungeKuttaSolver ( HelmholtzOperatorType &helmholtzOp,
85 TimeProviderType& timeProvider,
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() ),
97 gamma_( stages() ),
98 beta_( stages() ),
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())
105 {
106 setup( butcherTable );
107 }
108
109 template< class ButcherTable >
110 BasicROWRungeKuttaSolver ( HelmholtzOperatorType &helmholtzOp,
111 TimeProviderType& timeProvider,
112 const ButcherTable &butcherTable,
113 const TimeStepControlType &timeStepControl,
114 const SourceTermType &sourceTerm,
115 const Dune::Fem::ParameterReader &parameter = Dune::Fem::Parameter::container() )
116 : BasicROWRungeKuttaSolver( helmholtzOp, timeProvider, butcherTable, timeStepControl, sourceTerm, NonlinearSolverParameterType( parameter ) )
117 {}
118
125 template< class ButcherTable >
126 BasicROWRungeKuttaSolver ( HelmholtzOperatorType &helmholtzOp,
127 TimeProviderType& timeProvider,
128 const ButcherTable &butcherTable,
129 const TimeStepControlType &timeStepControl,
130 const NonlinearSolverParameterType& parameter )
131 : BasicROWRungeKuttaSolver( helmholtzOp, timeProvider, butcherTable, timeStepControl, SourceTermType(), parameter )
132 {}
133
134 template< class ButcherTable >
135 BasicROWRungeKuttaSolver ( HelmholtzOperatorType &helmholtzOp,
136 TimeProviderType& timeProvider,
137 const ButcherTable &butcherTable,
138 const TimeStepControlType &timeStepControl,
139 const Dune::Fem::ParameterReader &parameter = Dune::Fem::Parameter::container() )
140 : BasicROWRungeKuttaSolver( helmholtzOp, timeProvider, butcherTable, timeStepControl, SourceTermType(), NonlinearSolverParameterType( parameter ) )
141 {}
142
148 template< class ButcherTable >
149 BasicROWRungeKuttaSolver ( HelmholtzOperatorType &helmholtzOp,
150 TimeProviderType& timeProvider,
151 const ButcherTable &butcherTable,
152 const NonlinearSolverParameterType& parameter )
153 : BasicROWRungeKuttaSolver( helmholtzOp, timeProvider, butcherTable, TimeStepControlType(), SourceTermType(), parameter )
154 {}
155
156 template< class ButcherTable >
157 BasicROWRungeKuttaSolver ( HelmholtzOperatorType &helmholtzOp,
158 TimeProviderType& timeProvider,
159 const ButcherTable &butcherTable,
160 const Dune::Fem::ParameterReader &parameter = Dune::Fem::Parameter::container() )
161 : BasicROWRungeKuttaSolver( helmholtzOp, timeProvider, butcherTable, TimeStepControlType(), SourceTermType(), NonlinearSolverParameterType( parameter ) )
162 {}
163
164 template< class ButcherTable >
165 void setup( const ButcherTable& butcherTable )
166 {
168 {
169 std::cout << "ROW method of order=" << butcherTable.order() << " with " << stages_ << " stages" << std::endl;
170 }
171
172 // create intermediate functions
173 for( int i = 0; i < stages(); ++i )
174 {
175 std::ostringstream name;
176 name << "RK stage " << i;
177 update_[ i ] = new DestinationType( name.str(), helmholtzOp_.space() );
178 }
179
180 // compute coefficients
181 for( int i = 0; i < stages(); ++i )
182 gamma_[ i ] = alpha_[ i ][ i ];
183
184 alpha_.invert();
185 alpha_.mtv( butcherTable.b(), beta_ );
186 alpha2_.rightmultiply( alpha_ );
187 }
188
191 {
192 for( int i = 0; i < stages(); ++i )
193 delete update_[ i ];
194 }
195
197 void initialize ( const DestinationType &U0 )
198 {
199 const double time = timeStepControl_.time();
200
201 helmholtzOp_.setTime( time );
202 helmholtzOp_.initializeTimeStepSize( U0 );
203 const double helmholtzEstimate = helmholtzOp_.timeStepEstimate();
204
205 double sourceTermEstimate = sourceTerm_.initialTimeStepEstimate( time, U0 );
206 // negative time step is given by the empty source term
207 if( sourceTermEstimate < 0.0 ) sourceTermEstimate = helmholtzEstimate ;
208
209 timeStepControl_.initialTimeStepSize( helmholtzEstimate, sourceTermEstimate );
210 }
211
212 using BaseType::solve;
213
215 void solve ( DestinationType &U, MonitorType &monitor )
216 {
217 monitor.reset();
218
219 typename HelmholtzOperatorType::JacobianOperatorType jOp( "jacobianOperator", U.space(), U.space() );
220
221 const double time = timeStepControl_.time();
222 const double timeStepSize = timeStepControl_.timeStepSize();
223 assert( timeStepSize > 0.0 );
224 // std::cout << "solving... " << time << " : " << U << std::endl;
225 for( int s = 0; s < stages(); ++s )
226 {
227 // update for stage s
228 DestinationType& updateStage = *update_[ s ];
229
230 rhs_.assign( U );
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 ] );
237
238 rhs_.assign( updateStage );
239
240 // solve the system
241 const double stageTime = time + c_[ s ]*timeStepSize;
242 helmholtzOp_.setTime( stageTime );
243 // compute jacobian if the diagonal entry in the butcher tableau changes
244 // if ( s==0 || (gamma_[s-1] != gamma_[s]) )
245 {
246 // std::cout << "lambda=" << gamma_[ s ]*timeStepSize << std::endl;
247 helmholtzOp_.setLambda( gamma_[ s ]*timeStepSize );
248 helmholtzOp_.jacobian( U, jOp );
249 }
250 const int remLinearIts = maxLinearIterations_;
251
252 linearSolver_.parameter().setMaxIterations( remLinearIts );
253
254 if (preconditioner_)
255 linearSolver_.bind( jOp, *preconditioner_ );
256 else
257 linearSolver_.bind( jOp );
258
259 linearSolver_( rhs_, updateStage );
260 monitor.linearSolverIterations_ += linearSolver_.iterations();
261
262 linearSolver_.unbind();
263 }
264
265 double error = 0.0;
266 if(0 && timeStepControl_.computeError() )
267 {
268 // store U (to be revised)
269 DestinationType Uerr( U );
270
271 // update solution
272 U *= delta_;
273 for( int s = 0; s < stages(); ++s )
274 U.axpy( beta_[ s ], *update_[ s ] );
275
276 //error = infNorm( U, Uerr );
277 Uerr.axpy( -1.0, U );
278 const double errorU = Uerr.scalarProductDofs( Uerr );
279 const double normU = U.scalarProductDofs( U );
280
281 if( normU > 0 && errorU > 0 )
282 {
283 error = std::sqrt( errorU / normU );
284 }
285 std::cout << std::scientific << "Error in RK = " << error << " norm " << errorU << " " << normU << std::endl;
286 //std::cout << std::scientific << "Error in RK = " << error << std::endl;
287 }
288 else
289 {
290 // update solution
291 for( int s = 0; s < stages(); ++s )
292 U.axpy( beta_[ s ], *update_[ s ] );
293 }
294 // set error to monitor
295 monitor.error_ = error;
296
297 // update time step size
298 timeStepControl_.timeStepEstimate( helmholtzOp_.timeStepEstimate(), sourceTerm_.timeStepEstimate(), monitor );
299 }
300
301 int stages () const { return stages_; }
302
303 void description ( std::ostream &out ) const
304 {
305 out << "Generic " << stages() << "-stage implicit Runge-Kutta solver.\\\\" << std::endl;
306 }
307
308 protected:
309
310 double infNorm(const DestinationType& U, const DestinationType& Uerr ) const
311 {
312 typedef typename DestinationType :: ConstDofIteratorType ConstDofIteratorType ;
313 const ConstDofIteratorType uend = U.dend();
314 double res = 0;
315 for( ConstDofIteratorType u = U.dbegin(), uerr = Uerr.dbegin(); u != uend; ++u, ++uerr )
316 {
317 double uval = *u;
318 double uerrval = *uerr ;
319 double div = std::abs( std::max( uval, uerrval ) );
320
321 double norm = std::abs( uval - uerrval );
322 if( std::abs(div) > 1e-12 )
323 norm /= div;
324 res = std::max( res, norm );
325 }
326 return res;
327 }
328
329 HelmholtzOperatorType& helmholtzOp_;
330 LinearInverseOperatorType linearSolver_;
331
332 TimeStepControl timeStepControl_;
333 SourceTerm sourceTerm_;
334
335 int stages_;
336 double delta_;
337 Dune::DynamicMatrix< double > alpha_, alpha2_;
338 Dune::DynamicVector< double > gamma_, beta_, c_;
339
340 DestinationType rhs_,temp_;
341 std::vector< DestinationType * > update_;
342
343 const int maxLinearIterations_;
344
345 const PreconditionOperatorType *preconditioner_;
346 };
347
348} // namespace DuneODE
349
350#endif // #ifndef DUNE_FEM_SOLVER_RUNGEKUTTA_BASICROW_HH
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 &parameter)
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 &parameter)
constructor
Definition: basicrow.hh:149
BasicROWRungeKuttaSolver(HelmholtzOperatorType &helmholtzOp, TimeProviderType &timeProvider, const ButcherTable &butcherTable, const TimeStepControlType &timeStepControl, const NonlinearSolverParameterType &parameter)
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
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 27, 22:29, 2024)