00001 #ifndef ANIMAL_INTEGRATION_EXPLICIT_SOLVER_H
00002 #define ANIMAL_INTEGRATION_EXPLICIT_SOLVER_H
00003
00004 #include <animal/integration/solver.h>
00005
00006
00007
00008 namespace animal { namespace integration {
00009
00010
00011
00012
00022
00023
00024
00025 template
00026 <
00027 class DerivativeF,
00028 class StepF,
00029 class TraitsT
00030 >
00031
00032 struct Euler : public Solver< DerivativeF, StepF, TraitsT >
00033 {
00034
00035
00036
00037
00038
00040 typedef TraitsT Traits;
00041
00043 typedef typename Traits::Real Real;
00044
00046 typedef typename Traits::State State;
00047
00049 typedef typename Traits::CopyState CopyState;
00050
00052 typedef typename Traits::Derivative Derivative;
00053
00055 typedef typename Traits::SizeType SizeType;
00056
00057
00058
00063
00067 Euler
00068 (
00069 const DerivativeF& df = DerivativeF(),
00070 const StepF& sf = StepF(),
00071 const TraitsT& tr = Traits()
00072 )
00073 : Solver< DerivativeF, StepF, TraitsT >( df, sf, tr )
00074 {}
00075
00077 virtual ~Euler(){}
00078
00080
00081
00086
00095 void doStep
00096 (
00097 const State& initial_S,
00098 State& final_S,
00099 const Derivative& initial_D,
00100 const Real,
00101 const Real h
00102 )
00103 {
00104 applyStep( initial_S, final_S, initial_D, h );
00105 }
00106
00108
00109
00110 protected:
00111
00114
00116 void setSize( const SizeType ){}
00117
00119
00120 };
00121
00122
00123
00124
00125
00126
00137
00138
00139
00140 template
00141 <
00142 class DerivativeF,
00143 class StepF,
00144 class TraitsT
00145 >
00146
00147 struct Runge_Kutta_2 : public Solver< DerivativeF,StepF,TraitsT >
00148 {
00149
00151 typedef TraitsT Traits;
00152
00154 typedef typename Traits::Real Real;
00155
00157 typedef typename Traits::State State;
00158
00160 typedef typename Traits::CopyState CopyState;
00161
00163 typedef typename Traits::Derivative Derivative;
00164
00166 typedef typename Traits::SizeType SizeType;
00167
00168
00173
00177 Runge_Kutta_2
00178 (
00179 const DerivativeF& df = DerivativeF(),
00180 const StepF& sf = StepF(),
00181 const Traits& tr = Traits()
00182 )
00183 : Solver< DerivativeF,StepF,TraitsT >( df, sf, tr )
00184 {}
00185
00187 virtual ~Runge_Kutta_2(){}
00188
00190
00191
00196
00205 void doStep
00206 (
00207 const State& initial_S,
00208 State& final_S,
00209 const Derivative& D,
00210 const Real t,
00211 const Real h
00212 )
00213 {
00214 Real h_2 = 0.5*h;
00215
00216 applyStep(initial_S, tmp_S, D, h_2);
00217
00218 writeDerivative( tmp_S, D1, (t + h_2) );
00219 applyStep( initial_S, final_S, D1, h );
00220 }
00221
00223
00224 protected:
00225
00228
00230 CopyState tmp_S;
00231
00233 void setSize( const SizeType size )
00234 {
00235 traits.resize( tmp_S, size );
00236 }
00237
00239
00240 };
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00274
00275
00276
00277 template
00278 <
00279 class DerivativeF,
00280 class StepF,
00281 class TraitsT
00282 >
00283
00284 struct Runge_Kutta_4 : public Solver< DerivativeF,StepF,TraitsT >
00285 {
00286
00288 typedef TraitsT Traits;
00289
00291 typedef typename Traits::Real Real;
00292
00294 typedef typename Traits::State State;
00295
00297 typedef typename Traits::CopyState CopyState;
00298
00300 typedef typename Traits::Derivative Derivative;
00301
00303 typedef typename Traits::SizeType SizeType;
00304
00305
00310
00314 Runge_Kutta_4
00315 (
00316 const DerivativeF& df = DerivativeF(),
00317 const StepF& sf = StepF(),
00318 const Traits& tr = Traits()
00319 )
00320 : Solver< DerivativeF, StepF, TraitsT >( df, sf, tr )
00321 {}
00322
00324 virtual ~Runge_Kutta_4(){}
00325
00327
00328
00329
00334
00342 void doStep
00343 (
00344 const State& initial_S,
00345 State& final_S,
00346 const Derivative& initial_D,
00347 const Real t,
00348 const Real h
00349 )
00350 {
00351 Real h_2 = 0.5*h;
00352
00353 applyStep(initial_S, tmp_S, initial_D, h_2);
00354
00355 writeDerivative ( tmp_S, D2, (t + h_2) );
00356 applyStep( initial_S, tmp_S, D2, h_2 );
00357
00358 writeDerivative ( tmp_S, D3, (t + h_2) );
00359 applyStep( initial_S, tmp_S, D3, h );
00360
00361 writeDerivative ( tmp_S, D4, (t + h) );
00362
00363
00364 traits.rk4Step( initial_D, D2, D3, D4, final_D );
00365
00366 applyStep(initial_S, final_S, final_D, h/6 );
00367
00368 }
00369
00371
00372 protected:
00373
00376
00378 CopyState tmp_S;
00379
00381 Derivative D2, D3, D4;
00382
00384 Derivative final_D;
00385
00387 void setSize(const SizeType size)
00388 {
00389 traits.resize( tmp_S, size );
00390 traits.resize( D2, size );
00391 traits.resize( D3, size );
00392 traits.resize( D4, size );
00393 traits.resize( final_D, size );
00394 }
00395
00397
00398 };
00399
00400
00401
00402
00403
00404
00415
00416
00417
00418 template
00419 <
00420 int N,
00421 class DerivativeF,
00422 class StepF,
00423 class TraitsT
00424 >
00425
00426 struct Modified_Midpoint : public Solver< DerivativeF, StepF, TraitsT >
00427 {
00428
00429
00431 typedef TraitsT Traits;
00432
00434 typedef typename Traits::Real Real;
00435
00437 typedef typename Traits::State State;
00438
00440 typedef typename Traits::CopyState CopyState;
00441
00443 typedef typename Traits::Derivative Derivative;
00444
00446 typedef typename Traits::SizeType SizeType;
00447
00448
00453
00457 Modified_Midpoint
00458 (
00459 const DerivativeF& df = DerivativeF(),
00460 const StepF& sf = StepF(),
00461 const Traits& tr = Traits()
00462 )
00463 : Solver< DerivativeF, StepF, TraitsT >( df, sf, tr )
00464 {}
00465
00467
00472
00480 void doStep
00481 (
00482 const State& initial_S,
00483 State& final_S,
00484 const Derivative& initial_D,
00485 const Real t,
00486 const Real h
00487 )
00488 {
00489
00490 Real hsub = h/N;
00491 Real hhsub = 2.0*hsub;
00492
00493 traits.copy( initial_S, S1 );
00494
00495 applyStep( S1, S2, initial_D, hsub );
00496
00497
00498 for( int m = 1; m < (N - 1); m++ )
00499 {
00500 writeDerivative( S2, D1, (t + m*hsub) );
00501 applyStep(S1, S3, D1, hhsub);
00502 S1 = S2;
00503 S2 = S3;
00504 }
00505
00506
00507 writeDerivative( S2, D1, (t + (N - 1)*hsub) );
00508 applyStep( S1, S3, D1, hhsub );
00509
00510
00511 writeDerivative( S3, D1, (t + h) );
00512 applyStep( S3, S3, D1, hsub );
00513 traits.average( S2, S3, final_S );
00514
00515
00516
00517 }
00518
00520
00521
00522 protected:
00523
00526
00528 CopyState S1, S2, S3;
00529
00531 void setSize( const SizeType size )
00532 {
00533 traits.resize( S1, size );
00534 traits.resize( S2, size );
00535 traits.resize( S3, size );
00536 }
00537
00539
00540 };
00541
00542
00543
00544
00545
00546
00556
00557
00558
00559 template
00560 <
00561 class NStepF,
00562 class DerivativeF,
00563 class StepF,
00564 class TraitsT
00565 >
00566
00567 struct Modified_Midpoint_V : public Solver< DerivativeF, StepF, TraitsT >
00568 {
00569
00571 typedef TraitsT Traits;
00572
00574 typedef typename Traits::Real Real;
00575
00577 typedef typename Traits::State State;
00578
00580 typedef typename Traits::CopyState CopyState;
00581
00583 typedef typename Traits::Derivative Derivative;
00584
00586 typedef typename Traits::SizeType SizeType;
00587
00588
00589 NStepF nstep;
00590
00595
00599 Modified_Midpoint_V
00600 (
00601 const NStepF& nsf = NStepF(),
00602 const DerivativeF& df = DerivativeF(),
00603 const StepF& sf = StepF(),
00604 const Traits& tr = Traits()
00605 )
00606 : Solver< DerivativeF, StepF, TraitsT >( df, sf, tr )
00607 , nstep(nsf)
00608 {}
00609
00611 virtual ~Modified_Midpoint_V(){}
00612
00614
00619
00628 void doStep
00629 (
00630 const State& initial_S,
00631 State& final_S,
00632 const Derivative& initial_D,
00633 const Real t,
00634 const Real h
00635 )
00636 {
00637 unsigned int N = nstep( initial_S, t );
00638
00639 Real hsub = h/N;
00640 Real hhsub = 2.0*hsub;
00641
00642 S1 = initial_S;
00643
00644 applyStep( S1, S2, initial_D, hsub );
00645
00646
00647 for( unsigned int m = 1; m < (N - 1); m++ )
00648 {
00649 writeDerivative( S2, D1, (t + m*hsub) );
00650 applyStep(S1, S3, D1, hhsub);
00651 S1 = S2;
00652 S2 = S3;
00653 }
00654
00655
00656 writeDerivative( S2, D1, (t + (N - 1)*hsub) );
00657 applyStep( S1, S3, D1, hhsub );
00658
00659
00660 writeDerivative( S3, D1, (t + h) );
00661 applyStep( S3, S3, D1, hsub );
00662 traits.average( S2, S3, final_S );
00663
00664
00665
00666 }
00667
00669
00670
00671 protected:
00672
00675
00677 State S1, S2, S3;
00678
00680 void setSize( const SizeType size )
00681 {
00682 traits.resize( S1, size );
00683 traits.resize( S2, size );
00684 traits.resize( S3, size );
00685 }
00686
00688
00689 };
00690
00691
00692
00693
00694
00695
00699 template <class TraitsT>
00700
00701 struct NStep_Function
00702 {
00703 typedef typename TraitsT::Real Real;
00704 typedef typename TraitsT::State State;
00705 typedef typename TraitsT::Numerics Numerics;
00706
00708 unsigned int operator()
00709 (
00710 const State& S,
00711 const Real t
00712 )
00713 const;
00714
00715 };
00716
00717 }
00718 }
00719
00720
00721
00722 #endif // ANIMAL_INTEGRATION_EXPLICIT_SOLVER_H