Template Numerical Library: TNL::Solvers::ODE::ODESolver< Method, Vector, SolverMonitor, IsStatic > Struct Template Reference

Template Numerical Library version\ main:0b2c40fb1

Loading...
Searching...
No Matches
TNL::Solvers::ODE::ODESolver< Method, Vector, SolverMonitor, IsStatic > Struct Template Reference

Integrator or solver of systems of ordinary differential equations. More...

## Detailed Description

template<typename Method, typename Vector, typename SolverMonitor = IterativeSolverMonitor< typename Vector::RealType >, bool IsStatic = IsStaticArrayType< Vector >()>
struct TNL::Solvers::ODE::ODESolver< Method, Vector, SolverMonitor, IsStatic >

Integrator or solver of systems of ordinary differential equations.

This solver can be used for the numerical solution of ordinary differential equations having the following form:

\( \frac{d \vec u}{dt} = \vec f( t, \vec u) \text{ on } (0,T), \)

and the initial condition

\( \vec u( 0 ) = \vec u_{ini} \).

The vector \( \vec u(t) \) can be represented using different types of containers, depending on the size and nature of the ODE system:

1. Static vectors (TNL::Containers::StaticVector): This is suitable for small systems of ODEs with a fixed number of unknowns. Utilizing StaticVector allows the ODE solver to be executed within GPU kernels. This capability is particularly useful for scenarios like running multiple sequential solvers in parallel, as in the case of TNL::Algorithms::parallelFor.
2. Dynamic vectors (TNL::Containers::Vector or TNL::Containers::VectorView): These are preferred when dealing with large systems of ODEs, such as those arising in the solution of parabolic partial differential equations using the method of lines. In these instances, the solver typically handles a single, large-scale problem that can be executed in parallel internally.

The method, which is supposed to be used by the solver, is represented by the template parameter Method.

The following examples demonstrates the use the solver with the static vector

1#include <iostream>
2#include <fstream>
3#include <TNL/Containers/Vector.h>
4#include <TNL/Algorithms/parallelFor.h>
5#include <TNL/Containers/StaticVector.h>
6#include <TNL/Solvers/ODE/ODESolver.h>
7#include <TNL/Solvers/ODE/Methods/Euler.h>
8
10using MultiIndex = TNL::Containers::StaticArray< 3, int >;
11using Real = double;
13
14template< typename Device >
15void
16solveParallelODEs( const char* file_name )
17{
19 using StaticVector = TNL::Containers::StaticVector< 3, Real >;
20 using Method = TNL::Solvers::ODE::Methods::Euler< Real >;
21 using ODESolver = TNL::Solvers::ODE::ODESolver< Method, StaticVector >;
23
25 const Real final_t = 50.0;
26 const Real tau = 0.001;
27 const Real output_time_step = 0.005;
29
31 const Real sigma_min = 10.0;
32 const Real rho_min = 15.0;
33 const Real beta_min = 1.0;
34 const int parametric_steps = 4;
35 const Real sigma_step = 30.0 / ( parametric_steps - 1 );
36 const Real rho_step = 21.0 / ( parametric_steps - 1 );
37 const Real beta_step = 15.0 / ( parametric_steps - 1 );
38 const int output_time_steps = ceil( final_t / output_time_step ) + 1;
40
42 const int results_size( output_time_steps * parametric_steps * parametric_steps * parametric_steps );
43 TNL::Containers::Vector< StaticVector, Device > results( results_size, 0.0 );
44 auto results_view = results.getView();
46
48 auto f = [ = ] __cuda_callable__(
49 const Real& t,
50 const Real& tau,
51 const StaticVector& u,
52 StaticVector& fu,
53 const Real& sigma_i,
54 const Real& rho_j,
55 const Real& beta_k )
56 {
57 const Real& x = u[ 0 ];
58 const Real& y = u[ 1 ];
59 const Real& z = u[ 2 ];
60 fu[ 0 ] = sigma_i * ( y - x );
61 fu[ 1 ] = rho_j * x - y - x * z;
62 fu[ 2 ] = -beta_k * z + x * y;
63 };
65
67 auto solve = [ = ] __cuda_callable__( const MultiIndex& idx ) mutable
68 {
70 const Real sigma_i = sigma_min + idx[ 0 ] * sigma_step;
71 const Real rho_j = rho_min + idx[ 1 ] * rho_step;
72 const Real beta_k = beta_min + idx[ 2 ] * beta_step;
74
76 ODESolver solver;
77 solver.setTau( tau );
78 solver.setTime( 0.0 );
79 StaticVector u( 1.0, 1.0, 1.0 );
80 int time_step( 1 );
81 results_view[ ( idx[ 0 ] * parametric_steps + idx[ 1 ] ) * parametric_steps + idx[ 2 ] ] = u;
83
85 while( time_step < output_time_steps ) {
86 solver.setStopTime( TNL::min( solver.getTime() + output_time_step, final_t ) );
88 solver.solve( u, f, sigma_i, rho_j, beta_k );
90 const int k =
91 ( ( time_step++ * parametric_steps + idx[ 0 ] ) * parametric_steps + idx[ 1 ] ) * parametric_steps + idx[ 2 ];
92 results_view[ k ] = u;
93 }
95 };
97
99 const MultiIndex begin = { 0, 0, 0 };
100 const MultiIndex end = { parametric_steps, parametric_steps, parametric_steps };
101 TNL::Algorithms::parallelFor< Device >( begin, end, solve );
103
105 std::fstream file;
106 file.open( file_name, std::ios::out );
107 for( int sigma_idx = 0; sigma_idx < parametric_steps; sigma_idx++ )
108 for( int rho_idx = 0; rho_idx < parametric_steps; rho_idx++ )
109 for( int beta_idx = 0; beta_idx < parametric_steps; beta_idx++ ) {
110 Real sigma = sigma_min + sigma_idx * sigma_step;
111 Real rho = rho_min + rho_idx * rho_step;
112 Real beta = beta_min + beta_idx * beta_step;
113 file << "# sigma " << sigma << " rho " << rho << " beta " << beta << '\n';
114 for( int i = 0; i < output_time_steps - 1; i++ ) {
115 int offset = ( ( i * parametric_steps + sigma_idx ) * parametric_steps + rho_idx ) * parametric_steps + beta_idx;
116 auto u = results.getElement( offset );
117 file << u[ 0 ] << " " << u[ 1 ] << " " << u[ 2 ] << '\n';
118 }
119 file << '\n';
120 }
122}
123
124int
125main( int argc, char* argv[] )
126{
127 if( argc != 2 ) {
128 std::cout << "Usage: " << argv[ 0 ] << " <path to output directory>\n";
129 return EXIT_FAILURE;
130 }
131 TNL::String file_name( argv[ 1 ] );
132 file_name += "/StaticODESolver-LorenzParallelExample-result.out";
133
134 solveParallelODEs< TNL::Devices::Host >( file_name.getString() );
135#ifdef __CUDACC__
136 solveParallelODEs< TNL::Devices::Cuda >( file_name.getString() );
137#endif
138}
__cuda_callable__
#define __cuda_callable__
Definition Macros.h:49
std::fstream
std::cout
TNL::Containers::StaticArray
Array with constant size.
Definition StaticArray.h:21
TNL::Containers::StaticVector
Vector with constant size.
Definition StaticVector.h:19
TNL::Containers::Vector
Vector extends Array with algebraic operations.
Definition Vector.h:37
TNL::String
Class for managing strings.
Definition String.h:31
TNL::Algorithms::parallelFor
std::enable_if_t< std::is_integral_v< Begin > &&std::is_integral_v< End > > parallelFor(const Begin &begin, const End &end, typename Device::LaunchConfiguration launch_config, Function f, FunctionArgs... args)
Parallel for-loop function for 1D range specified with integral values.
Definition parallelFor.h:41
TNL::ceil
__cuda_callable__ auto ceil(const T &value) -> decltype(std::ceil(value))
This function returns the smallest integer value not less than the given value.
Definition Math.h:496
TNL::min
constexpr ResultType min(const T1 &a, const T2 &b)
This function returns minimum of two numbers.
Definition Math.h:24
std::fstream::open
T open(T... args)
TNL::Solvers::ODE::Methods::Euler
First order Euler method.
Definition Euler.h:15
TNL::Solvers::ODE::ODESolver
Integrator or solver of systems of ordinary differential equations.
Definition ODESolver.h:63

and with the dynamic vector

1#include <iostream>
2#include <TNL/Containers/Vector.h>
3#include <TNL/Solvers/ODE/ODESolver.h>
4#include <TNL/Solvers/ODE/Methods/Euler.h>
5#include "write.h"
6
7using Real = double;
8using Index = int;
9
10template< typename Device >
11void
12solveHeatEquation( const char* file_name )
13{
15 using Vector = TNL::Containers::Vector< Real, Device, Index >;
16 using VectorView = typename Vector::ViewType;
17 using Method = TNL::Solvers::ODE::Methods::Euler< Real >;
18 using ODESolver = TNL::Solvers::ODE::ODESolver< Method, Vector >;
20
21 /***
22 * Parameters of the discretisation
23 */
25 const Real final_t = 0.05;
26 const Real output_time_step = 0.005;
27 const Index n = 41;
28 const Real h = 1.0 / ( n - 1 );
29 const Real tau = 0.1 * h * h;
30 const Real h_sqr_inv = 1.0 / ( h * h );
32
33 /***
34 * Initial condition
35 */
37 Vector u( n );
38 u.forAllElements(
39 [ = ] __cuda_callable__( Index i, Real & value )
40 {
41 const Real x = i * h;
42 if( x >= 0.4 && x <= 0.6 )
43 value = 1.0;
44 else
45 value = 0.0;
46 } );
47 std::fstream file;
48 file.open( file_name, std::ios::out );
49 write( file, u, n, h, (Real) 0.0 );
51
52 /***
53 * Setup of the solver
54 */
56 ODESolver solver;
57 solver.setTau( tau );
58 solver.setTime( 0.0 );
60
61 /***
62 * Time loop
63 */
65 while( solver.getTime() < final_t ) {
66 solver.setStopTime( TNL::min( solver.getTime() + output_time_step, final_t ) );
68 auto f = [ = ] __cuda_callable__( Index i, const VectorView& u, VectorView& fu ) mutable
69 {
70 if( i == 0 || i == n - 1 ) // boundary nodes -> boundary conditions
71 fu[ i ] = 0.0;
72 else // interior nodes -> approximation of the second derivative
73 fu[ i ] = h_sqr_inv * ( u[ i - 1 ] - 2.0 * u[ i ] + u[ i + 1 ] );
74 };
77 auto time_stepping = [ = ]( const Real& t, const Real& tau, const VectorView& u, VectorView& fu )
78 {
80 TNL::Algorithms::parallelFor< Device >( 0, n, f, u, fu );
82 };
84 solver.solve( u, time_stepping );
85 write( file, u, n, h, solver.getTime() ); // write the current state to a file
86 }
88}
89
90int
91main( int argc, char* argv[] )
92{
93 if( argc != 2 ) {
94 std::cout << "Usage: " << argv[ 0 ] << " <path to output directory>\n";
95 return EXIT_FAILURE;
96 }
97 TNL::String file_name( argv[ 1 ] );
98 file_name += "/ODESolver-HeatEquationExample-result.out";
99
100 solveHeatEquation< TNL::Devices::Host >( file_name.getString() );
101#ifdef __CUDACC__
102 solveHeatEquation< TNL::Devices::Cuda >( file_name.getString() );
103#endif
104}

Template Parameters

  Method | is a method (one from TNL::Solvers::ODE namespace) which is supposed to be used for the numerical integration.
  Vector | is a vector (TNL::Containers::Vector, TNL::Containers::VectorView, or TNL::Containers::StaticVector) representing \( \vec x \in R^n \).

The documentation for this struct was generated from the following file:

- src/TNL/Solvers/ODE/ODESolver.h