Skip to content
Snippets Groups Projects
Commit 4cff4ed9 authored by Tomáš Oberhuber's avatar Tomáš Oberhuber Committed by Jakub Klinkovský
Browse files

Writing documentation on static euler solver.

parent ec0f49ae
No related branches found
No related tags found
1 merge request!125ODE solvers
......@@ -90,7 +90,7 @@ where \f$ c \f$ is a constant. We will solve it in parallel ODEs with different
In this example we also show, how to run it on GPU. Therefore we moved the main solver to separate function `solveParallelODEs` which has one template parameter `Device` telling on what device it is supposed to run. The results of particular ODEs are stored in a memory and at the end they are copied to a file with given filename `file_name`. The variable \f$ u \f$ is scalar therefore we represent it by the type `Real` in the solver (line 12). Next we define parameters of the ODE solver (`final_t`, `tau` and `output_time_step`, lines 14-16), interval for the parameter of the ODE \f$ c \in \langle c_{min}, c_{max} \rangle \f$ ( `c_min`, `c_max`, lines 17-18) and number of values `c_vals` (line 19) distributed equidistantly in the interval with step `c_step` (line 20). We use the number of different values of the parameter `c` as a range for the parallel for on the line 43. This parallel for processes the lambda function `solve` which is defined on the lines 28-42. It receives a parameter `idx` which is index of the value of the parameter `c`. We compute its value on the line 29. Next we create the ODE solver (line 30) and setup its parameters (lines 31-32). We set initial condition of the given ODE and we define variable `time_step` which counts checkpoints which we store in the memory in vector `results` allocated in the line 23 and accessed in the lambda function via vector view `results_view` (defined on the line 24). We iterate over the interval \f$ (0, T) \f$ in the while loop starting on the line 36. We set the stop time of the ODE solver (line 38) and we run the solver (line 39). Finally we store the result at given checkpoint into vector view `results_view`. If the solver runs on the GPU, it cannot write the checkpoints into a file. This is done in postprocessing in the lines 45-54.
Note, how we pass the value of parameter `c` to the lambda function `f`. The method `solve` of the ODE solvers(\ref TNL::Solvers::StaticEuler::solve, for example) accepts user defined parameters via [variadic templates](https://en.wikipedia.org/wiki/Variadic_template). It means that in addition to the variable `u` and the right-hand side `f` we can add any other parameters like `c` in this example (line 39). This parameter appears in the lambda function `f` (line 25). The reason for this is that the `nvcc` compiler (version 10.1) does not accept lambda function defined within another lambda function. If such a construction is accepted by a compiler, the lambda function `f` which can be defined within the lambda function `solve` and the variable `c` defined in the lambda function `solve` could be captured by `f`.
Note, how we pass the value of parameter `c` to the lambda function `f`. The method `solve` of the ODE solvers(\ref TNL::Solvers::ODE::StaticEuler::solve, for example) accepts user defined parameters via [variadic templates](https://en.wikipedia.org/wiki/Variadic_template). It means that in addition to the variable `u` and the right-hand side `f` we can add any other parameters like `c` in this example (line 39). This parameter appears in the lambda function `f` (line 25). The reason for this is that the `nvcc` compiler (version 10.1) does not accept lambda function defined within another lambda function. If such a construction is accepted by a compiler, the lambda function `f` which can be defined within the lambda function `solve` and the variable `c` defined in the lambda function `solve` could be captured by `f`.
The result of this example looks as follows:
......
......@@ -56,12 +56,20 @@ public:
/**
* \brief This method defines configuration entries for setup of the iterative solver.
*
* \param config is the config description.
* \param prefix is the prefix of the configuration parameters for this solver.
*/
static void
configSetup( Config::ConfigDescription& config, const String& prefix = "" );
/**
* \brief Method for setup of the iterative solver based on configuration parameters.
*
* \param parameters is the container for configuration parameters.
* \param prefix is the prefix of the configuration parameters for this solver.
* \return true if the parameters where parsed sucessfuly.
* \return false if the method did not succeed to read the configuration parameters.
*/
bool
setup( const Config::ParameterContainer& parameters, const String& prefix = "" );
......
......@@ -20,8 +20,8 @@ namespace ODE {
/**
* \brief Solver of ODEs with the first order of accuracy.
*
* This solver is based on the (Euler method)[https://en.wikipedia.org/wiki/Euler_method] for solving of
* (ordinary differential equations)[https://en.wikipedia.org/wiki/Ordinary_differential_equation] having the
* This solver is based on the [Euler method](https://en.wikipedia.org/wiki/Euler_method) for solving of
* [ordinary differential equations](https://en.wikipedia.org/wiki/Ordinary_differential_equation) having the
* following form:
*
* \f$ \frac{d \vec u}{dt} = \vec f( t, \vec u) \text{ on } (0,T) \f$
......@@ -49,138 +49,202 @@ namespace ODE {
*
* The result looks as follows:
*
* \include StaticODESolver-SineParallelExample.out
* \include StaticODESolver-SineParallelExample-Host.out
*
* \tparam Real is floating point number type, it is type of \f$ x \f$ in this case.
*/
template< typename Real >
class StaticEuler : public StaticExplicitSolver< Real, int >
{
public:
/**
* \brief Type of floating-point arithemtics.
*/
using RealType = Real;
/**
* \brief Type for indexing.
*/
using IndexType = int;
/**
* \brief Type of unknown variable \f$ x \f$.
*/
using VectorType = Real;
/**
* \brief Another alias for type of unknown variable \f$ x \f$.
*/
using DofVectorType = VectorType;
/**
* \brief Default constructor.
*/
__cuda_callable__
StaticEuler() = default;
/**
* \brief Static method for setup of configuration parameters.
*
* \param config is the config description.
* \param prefix is the prefix of the configuration parameters for this solver.
*/
static void configSetup( Config::ConfigDescription& config,
const String& prefix = "" );
/**
* \brief
*
* \param parameters is the container for configuration parameters.
* \param prefix is the prefix of the configuration parameters for this solver.
* \return true if the parameters where parsed sucessfuly.
* \return false if the method did not succeed to read the configuration parameters.
*/
bool setup( const Config::ParameterContainer& parameters,
const String& prefix = "" );
/**
* \brief This method sets the Courant number in the (CFL condition)[https://en.wikipedia.org/wiki/Courant%E2%80%93Friedrichs%E2%80%93Lewy_condition].
*
* This method sets the constant \f$ C \f$ in the Courant–Friedrichs–Lewy condition. It means that
*
* \f[ \Delta t = \frac{C}{\| f( t,x )\|} \f],
*
* if \f$ C > 0\f$. If \f$ C = 0 \f$ the time step stays fixed.
*
* \param c is the Courant number.
*/
__cuda_callable__
void setCourantNumber( const RealType& c );
/**
* \brief Getter for the Courant number.
*
* \return the Courant number.
*/
__cuda_callable__
const RealType& getCourantNumber() const;
/**
* \brief Solve ODE given by a lambda function.
*
* \tparam RHSFunction
* \param u
* \param rhs
* \return 'true' if steady state solution has been reached, 'false' otherwise.
*/
template< typename RHSFunction, typename... Args >
__cuda_callable__
bool solve( VectorType& u, RHSFunction&& rhs, Args... args );
protected:
DofVectorType k1;
RealType courantNumber = 0.0;
public:
/**
* \brief Type of floating-point arithemtics.
*/
using RealType = Real;
/**
* \brief Type for indexing.
*/
using IndexType = int;
/**
* \brief Type of unknown variable \f$ x \f$.
*/
using VectorType = Real;
/**
* \brief Alias for type of unknown variable \f$ x \f$.
*/
using DofVectorType = VectorType;
/**
* \brief Default constructor.
*/
__cuda_callable__
StaticEuler() = default;
/**
* \brief Static method for setup of configuration parameters.
*
* \param config is the config description.
* \param prefix is the prefix of the configuration parameters for this solver.
*/
static void
configSetup( Config::ConfigDescription& config, const String& prefix = "" );
/**
* \brief Method for setup of the explicit solver based on configuration parameters.
*
* \param parameters is the container for configuration parameters.
* \param prefix is the prefix of the configuration parameters for this solver.
* \return true if the parameters where parsed successfully.
* \return false if the method did not succeed to read the configuration parameters.
*/
bool
setup( const Config::ParameterContainer& parameters, const String& prefix = "" );
/**
* \brief This method sets the Courant number in the (CFL condition)[https://en.wikipedia.org/wiki/Courant%E2%80%93Friedrichs%E2%80%93Lewy_condition].
*
* This method sets the constant \f$ C \f$ in the Courant–Friedrichs–Lewy condition. It means that
*
* \f[ \Delta t = \frac{C}{\| f( t,x )\|}, \f]
*
* if \f$ C > 0\f$. If \f$ C = 0 \f$ the time step stays fixed.
*
* \param c is the Courant number.
*/
__cuda_callable__
void setCourantNumber( const RealType& c );
/**
* \brief Getter for the Courant number.
*
* \return the Courant number.
*/
__cuda_callable__
const RealType& getCourantNumber() const;
/**
* \brief Solve ODE given by a lambda function.
*
* \tparam RHSFunction is type of a lambda function representing the right-hand side of the ODE system.
* The definition of the lambda function reads as:
* ```
* auto f = [=] ( const Real& t, const Real& tau, const Vector& u, Vector& fu, Args... args ) {...}
* ```
* where `t` is the current time of the evolution, `tau` is the current time step, `u` is the solution at the current time,
* `fu` is variable/static vector into which the lambda function is suppsed to evaluate the function \f$ f(t, \vec x) \f$ at
* the current time \f$ t \f$.
* \param u is a variable/static vector representing the solution of the ODE system at current time.
* \param f is the lambda function representing the right-hand side of the ODE system.
* \param args are user define arguments which are passed to the lambda function `f`.
* \return `true` if steady state solution has been reached, `false` otherwise.
*/
template< typename RHSFunction, typename... Args >
__cuda_callable__
bool solve( VectorType& u, RHSFunction&& f, Args... args );
protected:
DofVectorType k1;
RealType courantNumber = 0.0;
};
/**
* \brief Solver of ODEs with the first order of accuracy.
*
* See \ref TNL::Solvers::ODE::StaticEuler.
*/
template< int Size_,
typename Real >
class StaticEuler< Containers::StaticVector< Size_, Real > >
: public StaticExplicitSolver< Real, int >
{
public:
static constexpr int Size = Size_;
using RealType = Real;
using IndexType = int;
using VectorType = TNL::Containers::StaticVector< Size, Real >;
using DofVectorType = VectorType;
__cuda_callable__
StaticEuler() = default;
static void configSetup( Config::ConfigDescription& config,
const String& prefix = "" );
bool setup( const Config::ParameterContainer& parameters,
const String& prefix = "" );
__cuda_callable__
void setCourantNumber( const RealType& cfl );
__cuda_callable__
const RealType& getCourantNumber() const;
template< typename RHSFunction, typename... Args >
__cuda_callable__
bool solve( VectorType& u, RHSFunction&& rhs, Args... args );
protected:
DofVectorType k1;
RealType courantNumber = 0.0;
public:
/**
* \brief Size of the ODE system.
*/
static constexpr int Size = Size_;
/**
* \brief Type of floating-point arithemtics.
*/
using RealType = Real;
/**
* \brief Type for indexing.
*/
using IndexType = int;
/**
* \brief Type of unknown variable \f$ x \f$.
*/
using VectorType = TNL::Containers::StaticVector< Size, Real >;
/**
* \brief Alias for type of unknown variable \f$ x \f$.
*/
using DofVectorType = VectorType;
/**
* \brief Default constructor.
*/
__cuda_callable__
StaticEuler() = default;
/**
* \brief Static method for setup of configuration parameters.
*
* \param config is the config description.
* \param prefix is the prefix of the configuration parameters for this solver.
*/
static void
configSetup( Config::ConfigDescription& config, const String& prefix = "" );
/**
* \brief Method for setup of the explicit solver based on configuration parameters.
*
* \param parameters is the container for configuration parameters.
* \param prefix is the prefix of the configuration parameters for this solver.
* \return true if the parameters where parsed successfully.
* \return false if the method did not succeed to read the configuration parameters.
*/
bool
setup( const Config::ParameterContainer& parameters, const String& prefix = "" );
/**
* \brief This method sets the Courant number in the (CFL condition)[https://en.wikipedia.org/wiki/Courant%E2%80%93Friedrichs%E2%80%93Lewy_condition].
*
* This method sets the constant \f$ C \f$ in the Courant–Friedrichs–Lewy condition. It means that
*
* \f[ \Delta t = \frac{C}{\| f( t,x )\|} \f],
*
* if \f$ C > 0\f$. If \f$ C = 0 \f$ the time step stays fixed.
*
* \param c is the Courant number.
*/
__cuda_callable__
void setCourantNumber( const RealType& cfl );
/**
* \brief Getter for the Courant number.
*
* \return the Courant number.
*/
__cuda_callable__
const RealType& getCourantNumber() const;
template< typename RHSFunction, typename... Args >
__cuda_callable__
bool solve( VectorType& u, RHSFunction&& rhs, Args... args );
protected:
DofVectorType k1;
RealType courantNumber = 0.0;
};
} // namespace ODE
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment