template<int Size_, class
Real>
class TNL::Solvers::ODE::StaticMerson< Containers::StaticVector< Size_, Real > >
Solver of ODEs with the first order of accuracy.
This solver is based on the Runge-Kutta-Merson method with adaptive choice of the integration time step for solving of ordinary differential equations having the following form:
\( \frac{d u}{dt} = f( t, u) \text{ on } (0,T) \)
\( u( 0 ) = u_{ini} \). It is supposed to be used when the unknown \( \vec x \in R^n \) is expressed by a Containers::StaticVector.
For problems where \( x\) is represented by floating-point number, see TNL::Solvers::ODE::StaticMerson. For problems where \( \vec x\) is represented by TNL::Containers::Vector or TNL::Containers::VectorView, see TNL::Solvers::ODE::Merson.
The following example demonstrates the use the solvers:
2#include <TNL/Containers/StaticVector.h>
3#include <TNL/Solvers/ODE/StaticEuler.h>
8main(
int argc,
char* argv[] )
12 const Real final_t = 25.0;
13 const Real tau = 0.001;
14 const Real output_time_step = 0.01;
15 const Real sigma = 10.0;
16 const Real rho = 28.0;
17 const Real beta = 8.0 / 3.0;
21 solver.setTime( 0.0 );
22 Vector u( 1.0, 2.0, 3.0 );
23 while( solver.getTime() < final_t ) {
24 solver.setStopTime( TNL::min( solver.getTime() + output_time_step, final_t ) );
25 auto f = [ = ](
const Real& t,
const Real& tau,
const Vector& u, Vector& fu )
27 const Real& x = u[ 0 ];
28 const Real& y = u[ 1 ];
29 const Real& z = u[ 2 ];
30 fu[ 0 ] = sigma * ( y - x );
31 fu[ 1 ] = rho * x - y - x * z;
32 fu[ 2 ] = -beta * z + x * y;
Vector with constant size.
Definition StaticVector.h:19
Solver of ODEs with the first order of accuracy.
Definition StaticEuler.h:52
Since this variant of the Euler solver is static, it can be used even inside of GPU kernels and so combined with TNL::Algorithms::parallelFor as demonstrated by the following example:
3#include <TNL/Solvers/ODE/StaticEuler.h>
4#include <TNL/Containers/Vector.h>
5#include <TNL/Algorithms/parallelFor.h>
6#include <TNL/Containers/StaticArray.h>
11template<
typename Device >
13solveParallelODEs(
const char* file_name )
17 const Real final_t = 50.0;
18 const Real tau = 0.001;
19 const Real output_time_step = 0.005;
20 const Real sigma_min( 10.0 ), rho_min( 15.0 ), beta_min( 1.0 );
21 const int parametric_steps = 4;
22 const Real sigma_step = 30.0 / ( parametric_steps - 1 );
23 const Real rho_step = 21.0 / ( parametric_steps - 1 );
24 const Real beta_step = 15.0 / ( parametric_steps - 1 );
25 const int output_time_steps = ceil( final_t / output_time_step ) + 1;
27 const int results_size( output_time_steps * parametric_steps * parametric_steps * parametric_steps );
29 auto results_view = results.getView();
38 const Real& x = u[ 0 ];
39 const Real& y = u[ 1 ];
40 const Real& z = u[ 2 ];
41 fu[ 0 ] = sigma_i * ( y - x );
42 fu[ 1 ] = rho_j * x - y - x * z;
43 fu[ 2 ] = -beta_k * z + x * y;
47 const Real sigma_i = sigma_min + i[ 0 ] * sigma_step;
48 const Real rho_j = rho_min + i[ 1 ] * rho_step;
49 const Real beta_k = beta_min + i[ 2 ] * beta_step;
53 solver.setTime( 0.0 );
54 Vector u( 1.0, 1.0, 1.0 );
56 results_view[ ( i[ 0 ] * parametric_steps + i[ 1 ] ) * parametric_steps + i[ 2 ] ] = u;
57 while( time_step < output_time_steps ) {
58 solver.setStopTime( TNL::min( solver.getTime() + output_time_step, final_t ) );
59 solver.solve( u, f, sigma_i, rho_j, beta_k );
61 ( ( time_step++ * parametric_steps + i[ 0 ] ) * parametric_steps + i[ 1 ] ) * parametric_steps + i[ 2 ];
62 results_view[ idx ] = u;
65 const MultiIndex begin = { 0, 0, 0 };
66 const MultiIndex end = { parametric_steps, parametric_steps, parametric_steps };
67 TNL::Algorithms::parallelFor< Device >( begin, end, solve );
70 file.
open( file_name, std::ios::out );
71 for(
int sigma_idx = 0; sigma_idx < parametric_steps; sigma_idx++ )
72 for(
int rho_idx = 0; rho_idx < parametric_steps; rho_idx++ )
73 for(
int beta_idx = 0; beta_idx < parametric_steps; beta_idx++ ) {
74 Real sigma = sigma_min + sigma_idx * sigma_step;
75 Real rho = rho_min + rho_idx * rho_step;
76 Real beta = beta_min + beta_idx * beta_step;
77 file <<
"# sigma " << sigma <<
" rho " << rho <<
" beta " << beta <<
std::endl;
78 for(
int i = 0; i < output_time_steps - 1; i++ ) {
79 int offset = ( ( i * parametric_steps + sigma_idx ) * parametric_steps + rho_idx ) * parametric_steps + beta_idx;
80 auto u = results.getElement( offset );
81 file << u[ 0 ] <<
" " << u[ 1 ] <<
" " << u[ 2 ] <<
std::endl;
88main(
int argc,
char* argv[] )
91 file_name +=
"/StaticODESolver-LorenzParallelExample-result.out";
93 solveParallelODEs< TNL::Devices::Host >( file_name.getString() );
95 solveParallelODEs< TNL::Devices::Cuda >( file_name.getString() );
#define __cuda_callable__
Definition Macros.h:49
Array with constant size.
Definition StaticArray.h:20
Vector extends Array with algebraic operations.
Definition Vector.h:36
Class for managing strings.
Definition String.h:30
- Template Parameters
-
Size | is size of the ODE system. |
Real | is floating point number type, it is type of \( x \) in this case. |