From 7063b32d20f33094c4b73eff5f9b9731d5c899e8 Mon Sep 17 00:00:00 2001
From: Tomas Oberhuber <tomas.oberhuber@fjfi.cvut.cz>
Date: Sun, 21 Sep 2014 13:37:46 +0200
Subject: [PATCH] Implementing the heat equation eoc test.

---
 .../tnl-run-heat-equation-eoc-test            |  27 ++-
 src/config/tnlConfigDelimiter.h               |   2 +-
 src/config/tnlConfigDescription.h             |  32 ++--
 src/config/tnlConfigEntry.h                   |   8 +-
 src/config/tnlConfigEntryBase.h               |   4 +-
 src/config/tnlConfigEntryList.h               |   8 +-
 src/config/tnlParameterContainer.cpp          |  12 +-
 src/config/tnlParameterContainer.h            |  44 ++---
 src/core/tnlDataElement.h                     |   4 +-
 src/core/tnlString.h                          |   4 +-
 src/functions/tnlFunctionDiscretizer.h        |   6 +-
 src/functions/tnlTestFunction.h               |   4 +-
 src/implementation/core/tnlString.cpp         |   4 +-
 .../functions/tnlFunctionDiscretizer_impl.h   |   5 +-
 .../functions/tnlTestFunction_impl.h          |  41 +++--
 .../tnlDirichletBoundaryConditions_impl.h     |   5 +-
 .../tnlDirichletBoundaryConditions.h          |   3 +-
 .../benchmarks/tnl-benchmark-linear-solvers.h |  14 +-
 tools/src/tnl-init.cpp                        |  11 ++
 tools/src/tnl-init.h                          | 173 ++++++++++--------
 20 files changed, 224 insertions(+), 187 deletions(-)

diff --git a/examples/heat-equation/tnl-run-heat-equation-eoc-test b/examples/heat-equation/tnl-run-heat-equation-eoc-test
index cec1fa19dd..365503ee46 100644
--- a/examples/heat-equation/tnl-run-heat-equation-eoc-test
+++ b/examples/heat-equation/tnl-run-heat-equation-eoc-test
@@ -1,14 +1,15 @@
 #!/bin/bash
 
-solverName="tnl-heat-equation-eoc-test"
 device="host"
-dimensions="1D 2D 3D"
-sizes1D="16 32 64 128 256 512"
+dimensions="1D" # 2D 3D"
+sizes1D="16" # 32 64 128 256 512"
 sizes2D="16 32 64 128 256 512"
 sizes3D="16 32 64 128"
 testFunctions="exp-bump"
 snapshotPeriod=0.1
 finalTime=1
+timeDependence="linear"
+solverName="tnl-heat-equation-eoc-test"
 
 setupTestFunction()
 {
@@ -54,7 +55,7 @@ setInitialCondition()
 {
    testFunction=$1
    tnl-init --function ${testFunction} \
-            --output-file init.tnl \
+            --output-file exact-u.tnl \
             --amplitude ${amplitude} \
             --wave-length ${waveLength} \
             --wave-length-x ${waveLengthX} \
@@ -68,7 +69,10 @@ setInitialCondition()
             --phase-x ${phaseX} \
             --phase-y ${phaseY} \
             --phase-z ${phaseZ} \
-            --sigma ${sigma}           
+            --sigma ${sigma} \
+            --test-function-time-dependence ${timeDependence} \
+            --snapshot-period ${snapshotPeriod} \
+            --final-time ${finalTime}
 }
 
 solve()
@@ -76,6 +80,7 @@ solve()
    timeDiscretisation=$1
    discreteSolver=$2
    ${solverName} --mesh mesh.tnl \
+                 --initial-condition exact-u-0000.tnl \
                  --time-discretisation ${timeDiscretisation} \
                  --discrete-solver ${discreteSolver} \
                  --test-function ${testFunction}\
@@ -93,6 +98,7 @@ solve()
                  --phase-y ${phaseY} \
                  --phase-z ${phaseZ} \
                  --sigma ${sigma} \
+                 --test-function-time-dependence ${timeDependence} \
                  --snapshot-period ${snapshotPeriod} \
                  --final-time ${finalTime}
 }
@@ -135,9 +141,14 @@ runTest()
          do
             mkdir -p $size
             cd $size
-               setupGrid $dim $size 
-               setInitialCondition $testFunction
-               solve explicit merson
+               if test ! -f computation-done;
+               then
+                  touch computation-in-progress
+                  setupGrid $dim $size 
+                  setInitialCondition $testFunction
+                  solve explicit merson
+                  mv computation-in-progress computation-done
+               fi
             cd ..
          done
 
diff --git a/src/config/tnlConfigDelimiter.h b/src/config/tnlConfigDelimiter.h
index 05faef71db..b006cf4ab3 100644
--- a/src/config/tnlConfigDelimiter.h
+++ b/src/config/tnlConfigDelimiter.h
@@ -20,7 +20,7 @@
 
 struct tnlConfigDelimiter : public tnlConfigEntryBase
 {
-   tnlConfigDelimiter( const char* delimiter )
+   tnlConfigDelimiter( const tnlString& delimiter )
    : tnlConfigEntryBase( "", delimiter, false )
    {
    };
diff --git a/src/config/tnlConfigDescription.h b/src/config/tnlConfigDescription.h
index ec9140d501..ded3dec864 100644
--- a/src/config/tnlConfigDescription.h
+++ b/src/config/tnlConfigDescription.h
@@ -35,24 +35,24 @@ class tnlConfigDescription
    tnlConfigDescription();
 
    template< typename EntryType >
-   void addEntry( const char* name,
-                  const char* description )
+   void addEntry( const tnlString& name,
+                  const tnlString& description )
    {
       currentEntry = new tnlConfigEntry< EntryType >( name, description, false );
       entries.Append( currentEntry );
    }
 
    template< typename EntryType >
-   void addRequiredEntry( const char* name,
-                          const char* description )
+   void addRequiredEntry( const tnlString& name,
+                          const tnlString& description )
    {
       currentEntry = new tnlConfigEntry< EntryType >( name, description, true );
       entries.Append( currentEntry );
    }
    
    template< typename EntryType >
-   void addEntry( const char* name,
-                  const char* description,
+   void addEntry( const tnlString& name,
+                  const tnlString& description,
                   const EntryType& defaultValue )
    {
       currentEntry = new tnlConfigEntry< EntryType >( name,
@@ -63,24 +63,24 @@ class tnlConfigDescription
    }
 
    template< typename EntryType >
-   void addList( const char* name,
-                 const char* description )
+   void addList( const tnlString& name,
+                 const tnlString& description )
    {
       currentEntry = new tnlConfigEntryList< EntryType >( name, description, false );
       entries.Append( currentEntry );
    }
 
    template< typename EntryType >
-   void addRequiredList( const char* name,
-                         const char* description )
+   void addRequiredList( const tnlString& name,
+                         const tnlString& description )
    {
       currentEntry = new tnlConfigEntryList< EntryType >( name, description, true );
       entries.Append( currentEntry );
    }
 
    template< typename EntryType >
-   void addList( const char* name,
-                 const char* description,
+   void addList( const tnlString& name,
+                 const tnlString& description,
                  const EntryType& defaultValue )
    {
       currentEntry = new tnlConfigEntryList< EntryType >( name,
@@ -103,13 +103,13 @@ class tnlConfigDescription
       ( ( tnlConfigEntry< tnlString >* ) currentEntry )->getEnumValues().Append( tnlString( entryEnum ) );
    }
 
-   void addDelimiter( const char* delimiter )
+   void addDelimiter( const tnlString& delimiter )
    {
       entries.Append( new tnlConfigDelimiter( delimiter ) );
       currentEntry = 0;
    }
 
-   const tnlConfigEntryBase* getEntry( const char* name ) const
+   const tnlConfigEntryBase* getEntry( const tnlString& name ) const
    {
       for( int i = 0; i < entries.getSize(); i++ )
          if( entries[ i ]->name == name )
@@ -122,7 +122,7 @@ class tnlConfigDescription
    //const tnlString getEntryType( const char* name ) const;
 
    //! Returns zero pointer if there is no default value
-   template< class T > const T* getDefaultValue( const char* name ) const
+   template< class T > const T* getDefaultValue( const tnlString& name ) const
    {
       int i;
       const int entries_num = entries. getSize();
@@ -138,7 +138,7 @@ class tnlConfigDescription
    }
    
    //! Returns zero pointer if there is no default value
-   template< class T > T* getDefaultValue( const char* name )
+   template< class T > T* getDefaultValue( const tnlString& name )
    {
       int i;
       const int entries_num = entries. getSize();
diff --git a/src/config/tnlConfigEntry.h b/src/config/tnlConfigEntry.h
index e3c6f3b384..b2849eb762 100644
--- a/src/config/tnlConfigEntry.h
+++ b/src/config/tnlConfigEntry.h
@@ -29,8 +29,8 @@ struct tnlConfigEntry : public tnlConfigEntryBase
 
    public:
 
-   tnlConfigEntry( const char* name,
-                   const char* description,
+   tnlConfigEntry( const tnlString& name,
+                   const tnlString& description,
                    bool required )
       : tnlConfigEntryBase( name,
                             description,
@@ -39,8 +39,8 @@ struct tnlConfigEntry : public tnlConfigEntryBase
          hasDefaultValue = false;
       }
 
-   tnlConfigEntry( const char* name,
-                   const char* description,
+   tnlConfigEntry( const tnlString& name,
+                   const tnlString& description,
                    bool required,
                    const EntryType& defaultValue)
       : tnlConfigEntryBase( name,
diff --git a/src/config/tnlConfigEntryBase.h b/src/config/tnlConfigEntryBase.h
index 83c9c5c423..613ea39d99 100644
--- a/src/config/tnlConfigEntryBase.h
+++ b/src/config/tnlConfigEntryBase.h
@@ -28,8 +28,8 @@ struct tnlConfigEntryBase
 
    bool hasDefaultValue;
 
-   tnlConfigEntryBase( const char* name,
-                       const char* description,
+   tnlConfigEntryBase( const tnlString& name,
+                       const tnlString& description,
                        bool required )
       : name( name ),
         description( description ),
diff --git a/src/config/tnlConfigEntryList.h b/src/config/tnlConfigEntryList.h
index 1761effff0..31f6a63730 100644
--- a/src/config/tnlConfigEntryList.h
+++ b/src/config/tnlConfigEntryList.h
@@ -29,8 +29,8 @@ struct tnlConfigEntryList : public tnlConfigEntryBase
 
    public:
 
-   tnlConfigEntryList( const char* name,
-                       const char* description,
+   tnlConfigEntryList( const tnlString& name,
+                       const tnlString& description,
                        bool required )
       : tnlConfigEntryBase( name,
                             description,
@@ -39,8 +39,8 @@ struct tnlConfigEntryList : public tnlConfigEntryBase
          hasDefaultValue = false;
       }
 
-   tnlConfigEntryList( const char* name,
-                       const char* description,
+   tnlConfigEntryList( const tnlString& name,
+                       const tnlString& description,
                        bool required,
                        const EntryType& defaultValue)
       : tnlConfigEntryBase( name,
diff --git a/src/config/tnlParameterContainer.cpp b/src/config/tnlParameterContainer.cpp
index b570bf7d67..a549ceb386 100644
--- a/src/config/tnlParameterContainer.cpp
+++ b/src/config/tnlParameterContainer.cpp
@@ -41,14 +41,14 @@ tnlParameterContainer :: tnlParameterContainer()
 {
 }
 //--------------------------------------------------------------------------
-bool tnlParameterContainer :: AddParameter( const char* name,
-                                            const char* value )
+bool tnlParameterContainer :: AddParameter( const tnlString& name,
+                                            const tnlString& value )
 {
    return parameters. Append( new tnlParameter< tnlString >( name, ::getType< tnlString >().getString(), tnlString( value ) ) );
 }
 //--------------------------------------------------------------------------
-bool tnlParameterContainer :: SetParameter( const char* name,
-                                            const char* value )
+bool tnlParameterContainer :: SetParameter( const tnlString& name,
+                                            const tnlString& value )
 {
    int i;
    for( i = 0; i < parameters. getSize(); i ++ )
@@ -57,7 +57,7 @@ bool tnlParameterContainer :: SetParameter( const char* name,
       {
          if( parameters[ i ] -> type == ::getType< tnlString >() )
          {
-            ( ( tnlParameter< tnlString > * ) parameters[ i ] ) -> value. setString( value );
+            ( ( tnlParameter< tnlString > * ) parameters[ i ] )->value = value;
             return true;
          }
          else
@@ -73,7 +73,7 @@ bool tnlParameterContainer :: SetParameter( const char* name,
    return AddParameter( name, value );
 };
 //--------------------------------------------------------------------------
-bool tnlParameterContainer :: CheckParameter( const char* name ) const
+bool tnlParameterContainer :: CheckParameter( const tnlString& name ) const
 {
    int i;
    const int parameters_num = parameters. getSize();
diff --git a/src/config/tnlParameterContainer.h b/src/config/tnlParameterContainer.h
index 2661122832..606350cf08 100644
--- a/src/config/tnlParameterContainer.h
+++ b/src/config/tnlParameterContainer.h
@@ -25,7 +25,8 @@
 
 struct tnlParameterBase
 {
-   tnlParameterBase( const char* _name, const char* _type )
+   tnlParameterBase( const tnlString& _name,
+                     const tnlString& _type )
    : name( _name ), type( _type ){};
  
    tnlString name, type;
@@ -34,9 +35,9 @@ struct tnlParameterBase
 
 template< class T > struct tnlParameter : public tnlParameterBase
 {
-   tnlParameter( const char* _name,
-               const char* _type,
-               const T& val )
+   tnlParameter( const tnlString& _name,
+                 const tnlString& _type,
+                 const T& val )
    : tnlParameterBase( _name, _type ), value( val ){};
 
    T value;
@@ -50,21 +51,23 @@ class tnlParameterContainer
 
    tnlParameterContainer();
 
-   template< class T > bool AddParameter( const char* name,
+   template< class T > bool AddParameter( const tnlString& name,
                                           const T& value );
 
-   bool AddParameter( const char* name, 
-                      const char* value );
+   bool AddParameter( const tnlString& name, 
+                      const tnlString& value );
 
-   bool CheckParameter( const char* name ) const;
+   bool CheckParameter( const tnlString& name ) const;
 
-   template< class T > bool SetParameter( const char* name,
+   template< class T > bool SetParameter( const tnlString& name,
                                           const T& value );
 
-   bool SetParameter( const char* name,
-                      const char* value );
+   bool SetParameter( const tnlString& name,
+                      const tnlString& value );
 
-   template< class T > bool GetParameter( const char* name, T& value, bool verbose = false ) const
+   template< class T > bool GetParameter( const tnlString& name,
+                                          T& value,
+                                          bool verbose = false ) const
    {
       int i;
       const int size = parameters. getSize();
@@ -79,18 +82,7 @@ class tnlParameterContainer
       return false;
    }
 
-   template< class T > const T& GetParameter( const char* name ) const
-   {
-      int i;
-      const int size = parameters. getSize();
-      for( i = 0; i < size; i ++ )
-         if( parameters[ i ] -> name == name )
-            return ( ( tnlParameter< T >* ) parameters[ i ] ) -> value;
-      cerr << "Unknown parameter " << name << endl;
-      abort();
-   }
-   
-   template< class T > T& GetParameter( const char* name )
+   template< class T > const T& GetParameter( const tnlString& name ) const
    {
       int i;
       const int size = parameters. getSize();
@@ -117,13 +109,13 @@ bool ParseCommandLine( int argc, char* argv[],
                        tnlParameterContainer& parameters,
                        bool printUsage = true );
 
-template< class T > bool tnlParameterContainer :: AddParameter( const char* name,
+template< class T > bool tnlParameterContainer :: AddParameter( const tnlString& name,
                                                                 const T& value )
 {
    return parameters. Append( new tnlParameter< T >( name, ::getType< T >(). getString(), value ) );
 };
 
-template< class T > bool tnlParameterContainer :: SetParameter( const char* name,
+template< class T > bool tnlParameterContainer :: SetParameter( const tnlString& name,
                                                                 const T& value )
 {
    int i;
diff --git a/src/core/tnlDataElement.h b/src/core/tnlDataElement.h
index 2f79172d64..ae53cc8ae7 100644
--- a/src/core/tnlDataElement.h
+++ b/src/core/tnlDataElement.h
@@ -38,8 +38,8 @@ template< class T > class tnlDataElement
 
    //! Constructor with given data and possibly pointer to next element
    tnlDataElement( const T& dt, 
-                  tnlDataElement< T >* prv = 0,
-                  tnlDataElement< T >* nxt = 0 )
+                   tnlDataElement< T >* prv = 0,
+                   tnlDataElement< T >* nxt = 0 )
       : data( dt ), 
         next( nxt ),
         previous( prv ){};
diff --git a/src/core/tnlString.h b/src/core/tnlString.h
index c784d55936..ef6c024b69 100644
--- a/src/core/tnlString.h
+++ b/src/core/tnlString.h
@@ -105,10 +105,10 @@ class tnlString
    tnlString& operator += ( const tnlString& str );
  
    //! Operator +
-   tnlString operator + ( const tnlString& str );
+   tnlString operator + ( const tnlString& str ) const;
 
    //! Operator +
-   tnlString operator + ( const char* str );
+   tnlString operator + ( const char* str ) const;
 
    //! Comparison operator 
    bool operator == ( const tnlString& str ) const;
diff --git a/src/functions/tnlFunctionDiscretizer.h b/src/functions/tnlFunctionDiscretizer.h
index b44addeb7a..8725057c07 100644
--- a/src/functions/tnlFunctionDiscretizer.h
+++ b/src/functions/tnlFunctionDiscretizer.h
@@ -31,14 +31,16 @@ class tnlFunctionDiscretizer
              int ZDiffOrder >
    static void discretize( const Mesh& mesh,
                            const Function& function,
-                           Vector& discreteFunction );
+                           Vector& discreteFunction,
+                           const typename Vector::RealType& time = 0 );
 #else
    template< int XDiffOrder = 0,
              int YDiffOrder = 0,
              int ZDiffOrder = 0 >
    static void discretize( const Mesh& mesh,
                            const Function& function,
-                           Vector& discreteFunction );
+                           Vector& discreteFunction,
+                           const typename Vector::RealType& time = 0 );
 #endif   
    
 };
diff --git a/src/functions/tnlTestFunction.h b/src/functions/tnlTestFunction.h
index 7191fde13a..215d921c70 100644
--- a/src/functions/tnlTestFunction.h
+++ b/src/functions/tnlTestFunction.h
@@ -66,7 +66,7 @@ class tnlTestFunction
    __device__ __host__
 #endif
    Real getValue( const Vertex& vertex,
-                  const Real& time ) const;
+                  const Real& time = 0 ) const;
 
 #ifdef HAVE_NOT_CXX11
    template< int XDiffOrder,
@@ -83,7 +83,7 @@ class tnlTestFunction
    __device__ __host__
 #endif
    Real getTimeDerivative( const Vertex& vertex,
-                           const Real& time ) const;
+                           const Real& time = 0 ) const;
 
    ~tnlTestFunction();
 
diff --git a/src/implementation/core/tnlString.cpp b/src/implementation/core/tnlString.cpp
index cabbc8840f..231084e50c 100644
--- a/src/implementation/core/tnlString.cpp
+++ b/src/implementation/core/tnlString.cpp
@@ -175,12 +175,12 @@ tnlString& tnlString :: operator += ( const tnlString& str )
    return operator += ( str. getString() );
 }
 
-tnlString tnlString :: operator + ( const tnlString& str )
+tnlString tnlString :: operator + ( const tnlString& str ) const
 {
    return tnlString( *this ) += str;
 }
 
-tnlString tnlString :: operator + ( const char* str )
+tnlString tnlString :: operator + ( const char* str ) const
 {
    return tnlString( *this ) += str;
 }
diff --git a/src/implementation/functions/tnlFunctionDiscretizer_impl.h b/src/implementation/functions/tnlFunctionDiscretizer_impl.h
index 70dba155f3..3eab02a171 100644
--- a/src/implementation/functions/tnlFunctionDiscretizer_impl.h
+++ b/src/implementation/functions/tnlFunctionDiscretizer_impl.h
@@ -22,7 +22,8 @@ template< typename Mesh, typename Function, typename Vector >
    template< int XDiffOrder, int YDiffOrder, int ZDiffOrder >
 void tnlFunctionDiscretizer< Mesh, Function, Vector >::discretize( const Mesh& mesh,
                                                                    const Function& function,
-                                                                   Vector& discreteFunction )
+                                                                   Vector& discreteFunction,
+                                                                   const typename Vector::RealType& time )
 {
    //tnlAssert( Mesh::Dimensions == Function::Dimensions, ); // TODO: change this to tnlStaticAssert
    typename Mesh::IndexType i = 0;
@@ -35,7 +36,7 @@ void tnlFunctionDiscretizer< Mesh, Function, Vector >::discretize( const Mesh& m
          typename Mesh::CoordinatesType c;
          c = mesh.getCellCoordinates( i );
          v = mesh.getCellCenter( c );
-         discreteFunction[ i ] = function.template getValue< XDiffOrder, YDiffOrder, ZDiffOrder >( v );
+         discreteFunction[ i ] = function.template getValue< XDiffOrder, YDiffOrder, ZDiffOrder >( v, time );
          i++;
       }
    }
diff --git a/src/implementation/functions/tnlTestFunction_impl.h b/src/implementation/functions/tnlTestFunction_impl.h
index c4a8a78a3e..3eb99ea8eb 100644
--- a/src/implementation/functions/tnlTestFunction_impl.h
+++ b/src/implementation/functions/tnlTestFunction_impl.h
@@ -43,7 +43,7 @@ tnlTestFunction< FunctionDimensions, Real, Device >::
 configSetup( tnlConfigDescription& config,
              const tnlString& prefix )
 {
-   config.addEntry     < tnlString >( "test-function", "Testing function.", "exp-bump" );
+   config.addEntry     < tnlString >( prefix + "test-function", "Testing function.", "exp-bump" );
       config.addEntryEnum( "sin-wave" );
       config.addEntryEnum( "sin-bumps" );
       config.addEntryEnum( "exp-bump" );
@@ -62,12 +62,12 @@ configSetup( tnlConfigDescription& config,
    config.addEntry     < double >( prefix + "waves-number-y", "Cut-off for the sine based test functions.", 0.0 );
    config.addEntry     < double >( prefix + "waves-number-z", "Cut-off for the sine based test functions.", 0.0 );
    config.addEntry     < double >( prefix + "sigma", "Sigma for the exp based test functions.", 1.0 );
-   config.addEntry     < tnlString >( "test-function-time-dependence", "Time dependence of the test function.", "none" );
+   config.addEntry     < tnlString >( prefix + "test-function-time-dependence", "Time dependence of the test function.", "none" );
       config.addEntryEnum( "none" );
       config.addEntryEnum( "linear" );
       config.addEntryEnum( "quadratic" );
       config.addEntryEnum( "cosine" );
-   config.addEntry     < double >( prefix + "time-scale", "Time scaling for the time dependenc of the test function.", 1.0 );
+   config.addEntry     < double >( prefix + "time-scale", "Time scaling for the time dependency of the test function.", 1.0 );
 
 }
 
@@ -89,11 +89,11 @@ initFunction( const tnlParameterContainer& parameters,
 
    if( Device::DeviceType == ( int ) tnlHostDevice )
    {
-      function = auxFunction;
+      this->function = auxFunction;
    }
    if( Device::DeviceType == ( int ) tnlCudaDevice )
    {
-      function = tnlCuda::passToDevice( *auxFunction );
+      this->function = tnlCuda::passToDevice( *auxFunction );
       delete auxFunction;
       if( ! checkCudaDevice )
          return false;
@@ -109,8 +109,22 @@ tnlTestFunction< FunctionDimensions, Real, Device >::
 init( const tnlParameterContainer& parameters,
       const tnlString& prefix )
 {
-   const tnlString& testFunction = parameters.GetParameter< tnlString >( "test-function" );
+   const tnlString& timeDependence =
+            parameters.GetParameter< tnlString >(
+                     prefix +
+                     "test-function-time-dependence" );
+   if( timeDependence == "none" )
+      this->timeDependence = none;
+   if( timeDependence == "linear" )
+      this->timeDependence = linear;
+   if( timeDependence == "quadratic" )
+      this->timeDependence = quadratic;
+   if( timeDependence == "sine" )
+      this->timeDependence = sine;
 
+   this->timeScale = parameters.GetParameter< double >( prefix + "time-scale" );
+
+   const tnlString& testFunction = parameters.GetParameter< tnlString >( prefix + "test-function" );
    if( testFunction == "constant" )
    {
       typedef tnlConstantFunction< Dimensions, Real > FunctionType;
@@ -135,18 +149,6 @@ init( const tnlParameterContainer& parameters,
       functionType = sinWave;
       return initFunction< FunctionType >( parameters );
    }
-
-   const tnlString& timeDependence = parameters.GetParameter< tnlString >( "test-function-time-dependence" );
-   if( timeDependence == "none" )
-      this->timeDependence = none;
-   if( timeDependence == "linear" )
-      this->timeDependence = linear;
-   if( timeDependence == "quadratic" )
-      this->timeDependence = quadratic;
-   if( timeDependence == "sine" )
-      this->timeDependence = sine;
-
-   this->timeScale = parameters.GetParameter< tnlString >( "time-scale" );
 }
 
 template< int FunctionDimensions,
@@ -165,7 +167,7 @@ getValue( const Vertex& vertex,
           const Real& time ) const
 {
    Real scale( 1.0 );
-   switch( timeDependence )
+   switch( this->timeDependence )
    {
       case none:
          break;
@@ -181,6 +183,7 @@ getValue( const Vertex& vertex,
          scale = 1.0 - sin( this->timeScale * time );
          break;
    }
+   //cout << "scale = " << scale << " time= " << time << " timeScale = " << timeScale << " timeDependence = " << ( int ) timeDependence << endl;
    switch( functionType )
    {
       case constant:
diff --git a/src/implementation/operators/tnlDirichletBoundaryConditions_impl.h b/src/implementation/operators/tnlDirichletBoundaryConditions_impl.h
index 7928fa5176..18685874b0 100644
--- a/src/implementation/operators/tnlDirichletBoundaryConditions_impl.h
+++ b/src/implementation/operators/tnlDirichletBoundaryConditions_impl.h
@@ -10,9 +10,10 @@ template< typename MeshReal,
           typename Index >
 bool
 tnlDirichletBoundaryConditions< tnlGrid< 1,MeshReal, Device, MeshIndex >, Function, Real, Index >::
-init( const tnlParameterContainer& parameters )
+init( const tnlParameterContainer& parameters,
+      const tnlString& prefix )
 {
-   return function.init( parameters, "boundary-conditions-" );
+   return function.init( parameters, prefix );
 }
 
 template< typename MeshReal,
diff --git a/src/operators/tnlDirichletBoundaryConditions.h b/src/operators/tnlDirichletBoundaryConditions.h
index e06b56ed93..b03e97d258 100644
--- a/src/operators/tnlDirichletBoundaryConditions.h
+++ b/src/operators/tnlDirichletBoundaryConditions.h
@@ -35,7 +35,8 @@ class tnlDirichletBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >,
    typedef tnlStaticVector< 1, RealType > VertexType;
    typedef typename MeshType::CoordinatesType CoordinatesType;
             
-   bool init( const tnlParameterContainer& parameters );
+   bool init( const tnlParameterContainer& parameters,
+              const tnlString& prefix = "" );
 
    void setBoundaryConditions( const RealType& time,
                                const RealType& tau,
diff --git a/tests/benchmarks/tnl-benchmark-linear-solvers.h b/tests/benchmarks/tnl-benchmark-linear-solvers.h
index d241ba19ba..35f5fee63f 100644
--- a/tests/benchmarks/tnl-benchmark-linear-solvers.h
+++ b/tests/benchmarks/tnl-benchmark-linear-solvers.h
@@ -58,13 +58,13 @@ void configSetup( tnlConfigDescription& config )
    config.addEntry< tnlString >( "log-file", "Log file name.", "tnl-benchmark-linear-solvers.log");
    config.addEntry< tnlString >( "precison", "Precision of the arithmetics.", "double" );
    config.addEntry< tnlString >( "matrix-format", "Matrix format.", "csr" );
-      config.addEntryEnum( "dense" );
-      config.addEntryEnum( "tridiagonal" );
-      config.addEntryEnum( "multidiagonal" );
-      config.addEntryEnum( "ellpack" );
-      config.addEntryEnum( "sliced-ellpack" );
-      config.addEntryEnum( "chunked-ellpack" );
-      config.addEntryEnum( "csr" );
+      config.addEntryEnum< tnlString >( "dense" );
+      config.addEntryEnum< tnlString >( "tridiagonal" );
+      config.addEntryEnum< tnlString >( "multidiagonal" );
+      config.addEntryEnum< tnlString >( "ellpack" );
+      config.addEntryEnum< tnlString >( "sliced-ellpack" );
+      config.addEntryEnum< tnlString >( "chunked-ellpack" );
+      config.addEntryEnum< tnlString >( "csr" );
    config.addEntry< tnlString >( "solver", "Linear solver.", "gmres" );
       config.addEntryEnum< tnlString >( "sor" );
       config.addEntryEnum< tnlString >( "cg" );
diff --git a/tools/src/tnl-init.cpp b/tools/src/tnl-init.cpp
index 9e75b5af32..0fb093fa4a 100644
--- a/tools/src/tnl-init.cpp
+++ b/tools/src/tnl-init.cpp
@@ -30,6 +30,17 @@ void setupConfig( tnlConfigDescription& config )
 {
    config.addDelimiter                            ( "General settings:" );
    config.addEntry< tnlString >( "mesh", "Mesh file. If none is given, a regular rectangular mesh is assumed.", "mesh.tnl" );
+   config.addEntry< tnlString >( "real-type", "Precision of the function evaluation.", "mesh-real-type" );
+      config.addEntryEnum< tnlString >( "mesh-real-type" );
+      config.addEntryEnum< tnlString >( "float" );
+      config.addEntryEnum< tnlString >( "double" );
+      config.addEntryEnum< tnlString >( "long-double" );
+   config.addEntry< double >( "final-time", "Final time for a serie of snapshots of the time-dependent function.", 0.0 );
+   config.addEntry< double >( "snapshot-period", "Period between snapshots in a serie of the time-dependent function.", 0.0 );
+   config.addEntry< int >( "x-derivative", "Order of the partial derivative w.r.t x.", 0 );
+   config.addEntry< int >( "y-derivative", "Order of the partial derivative w.r.t y.", 0 );
+   config.addEntry< int >( "z-derivative", "Order of the partial derivative w.r.t <.", 0 );
+   config.addEntry< bool >( "numerical-differentiation", "The partial derivatives will be computed numerically.", false );
    config.addRequiredEntry< tnlString >( "function", "Function name." );
       config.addEntryEnum< tnlString >( "exp-bump" );
       config.addEntryEnum< tnlString >( "sin-bumps" );
diff --git a/tools/src/tnl-init.h b/tools/src/tnl-init.h
index 1be06eaa73..1163ca0a79 100644
--- a/tools/src/tnl-init.h
+++ b/tools/src/tnl-init.h
@@ -22,13 +22,12 @@
 #include <core/vectors/tnlVector.h>
 #include <mesh/tnlGrid.h>
 #include <functions/tnlFunctionDiscretizer.h>
-#include <functions/tnlSinWaveFunction.h>
-#include <functions/tnlSinBumpsFunction.h>
-#include <functions/tnlExpBumpFunction.h>
+#include <functions/tnlTestFunction.h>
 #include <operators/tnlFiniteDifferences.h>
+#include <core/mfilename.h>
 
 template< typename MeshType,
-          typename FunctionType,
+          typename RealType,
           int xDiff,
           int yDiff,
           int zDiff >
@@ -40,37 +39,63 @@ bool renderFunction( const tnlParameterContainer& parameters )
    if( ! mesh.load( meshFile ) )
       return false;
 
+   typedef tnlTestFunction< MeshType::Dimensions, RealType > FunctionType;
    FunctionType function;
    if( ! function.init( parameters, "" ) )
       return false;
-   typedef tnlVector< typename MeshType::RealType, tnlHost, typename MeshType::IndexType > DiscreteFunctionType;
+   typedef tnlVector< RealType, tnlHost, typename MeshType::IndexType > DiscreteFunctionType;
    DiscreteFunctionType discreteFunction;
    if( ! discreteFunction.setSize( mesh.getNumberOfCells() ) )
       return false;
 
-   bool approximateDerivatives = parameters.GetParameter< bool >( "approximate-derivatives" );
-   if( approximateDerivatives )
+   double time( 0.0 );
+   double finalTime = parameters.GetParameter< double >( "final-time" );
+   double tau = parameters.GetParameter< double >( "snapshot-period" );
+   bool numericalDifferentiation = parameters.GetParameter< bool >( "numerical-differentiation" );
+   int step( 0 );
+
+   while( time <= finalTime )
    {
-      cout << "+ -> Computing the finite differences ... " << endl;
-      DiscreteFunctionType auxDiscreteFunction;
-      if( ! auxDiscreteFunction.setSize( mesh.getNumberOfCells() ) )
+
+      if( numericalDifferentiation )
+      {
+         cout << "+ -> Computing the finite differences ... " << endl;
+         DiscreteFunctionType auxDiscreteFunction;
+         if( ! auxDiscreteFunction.setSize( mesh.getNumberOfCells() ) )
+            return false;
+         tnlFunctionDiscretizer< MeshType, FunctionType, DiscreteFunctionType >::template discretize< 0, 0, 0 >( mesh, function, auxDiscreteFunction, time );
+         tnlFiniteDifferences< MeshType >::template getDifference< DiscreteFunctionType, xDiff, yDiff, zDiff, 0, 0, 0 >( mesh, auxDiscreteFunction, discreteFunction );
+      }
+      else
+      {
+         tnlFunctionDiscretizer< MeshType, FunctionType, DiscreteFunctionType >::template discretize< xDiff, yDiff, zDiff >( mesh, function, discreteFunction, time );
+      }
+
+      tnlString outputFile = parameters.GetParameter< tnlString >( "output-file" );
+      if( finalTime > 0.0 )
+      {
+         tnlString extension = tnlString( "." ) + getFileExtension( outputFile );
+         RemoveFileExtension( outputFile );
+         outputFile += "-";
+         tnlString aux;
+         FileNameBaseNumberEnding( outputFile.getString(),
+                                   step,
+                                   5,
+                                   extension.getString(),
+                                   aux );
+         outputFile = aux;
+      }
+      cout << "+ -> Writing the function to " << outputFile << " ... " << endl;
+      if( ! discreteFunction.save( outputFile) )
          return false;
-      tnlFunctionDiscretizer< MeshType, FunctionType, DiscreteFunctionType >::template discretize< 0, 0, 0 >( mesh, function, auxDiscreteFunction );
-      tnlFiniteDifferences< MeshType >::template getDifference< DiscreteFunctionType, xDiff, yDiff, zDiff, 0, 0, 0 >( mesh, auxDiscreteFunction, discreteFunction );
-   }
-   else
-   {
-      tnlFunctionDiscretizer< MeshType, FunctionType, DiscreteFunctionType >::template discretize< xDiff, yDiff, zDiff >( mesh, function, discreteFunction );
+      time += tau;
+      step ++;
    }
-
-   tnlString outputFile = parameters.GetParameter< tnlString >( "output-file" );
-   cout << "+ -> Writing the function to " << outputFile << " ... " << endl;
-   if( ! discreteFunction.save( outputFile) )
-      return false;
    return true;
 }
 
-template< typename MeshType, typename FunctionType >
+template< typename MeshType,
+          typename RealType >
 bool resolveDerivatives( const tnlParameterContainer& parameters )
 {
 
@@ -86,103 +111,93 @@ bool resolveDerivatives( const tnlParameterContainer& parameters )
       return false;
    }
    if( xDiff == 0 && yDiff == 0 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 0, 0, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 0, 0 >( parameters );
    if( xDiff == 0 && yDiff == 0 && zDiff == 1 )
-      return renderFunction< MeshType, FunctionType, 0, 0, 1 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 0, 1 >( parameters );
    if( xDiff == 0 && yDiff == 0 && zDiff == 2 )
-      return renderFunction< MeshType, FunctionType, 0, 0, 2 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 0, 2 >( parameters );
    if( xDiff == 0 && yDiff == 0 && zDiff == 3 )
-      return renderFunction< MeshType, FunctionType, 0, 0, 3 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 0, 3 >( parameters );
    if( xDiff == 0 && yDiff == 0 && zDiff == 4 )
-      return renderFunction< MeshType, FunctionType, 0, 0, 4 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 0, 4 >( parameters );
    if( xDiff == 0 && yDiff == 1 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 0, 1, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 1, 0 >( parameters );
    if( xDiff == 0 && yDiff == 1 && zDiff == 1 )
-      return renderFunction< MeshType, FunctionType, 0, 1, 1 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 1, 1 >( parameters );
    if( xDiff == 0 && yDiff == 1 && zDiff == 2 )
-      return renderFunction< MeshType, FunctionType, 0, 1, 2 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 1, 2 >( parameters );
    if( xDiff == 0 && yDiff == 1 && zDiff == 3 )
-      return renderFunction< MeshType, FunctionType, 0, 1, 3 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 1, 3 >( parameters );
    if( xDiff == 0 && yDiff == 2 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 0, 2, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 2, 0 >( parameters );
    if( xDiff == 0 && yDiff == 2 && zDiff == 1 )
-      return renderFunction< MeshType, FunctionType, 0, 2, 1 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 2, 1 >( parameters );
    if( xDiff == 0 && yDiff == 2 && zDiff == 2 )
-      return renderFunction< MeshType, FunctionType, 0, 2, 2 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 2, 2 >( parameters );
    if( xDiff == 0 && yDiff == 3 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 0, 3, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 3, 0 >( parameters );
    if( xDiff == 0 && yDiff == 3 && zDiff == 1 )
-      return renderFunction< MeshType, FunctionType, 0, 3, 1 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 3, 1 >( parameters );
    if( xDiff == 0 && yDiff == 4 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 0, 4, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 0, 4, 0 >( parameters );
    if( xDiff == 1 && yDiff == 0 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 1, 0, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 1, 0, 0 >( parameters );
    if( xDiff == 1 && yDiff == 0 && zDiff == 1 )
-      return renderFunction< MeshType, FunctionType, 1, 0, 1 >( parameters );
+      return renderFunction< MeshType, RealType, 1, 0, 1 >( parameters );
    if( xDiff == 1 && yDiff == 0 && zDiff == 2 )
-      return renderFunction< MeshType, FunctionType, 1, 0, 2 >( parameters );
+      return renderFunction< MeshType, RealType, 1, 0, 2 >( parameters );
    if( xDiff == 1 && yDiff == 0 && zDiff == 3 )
-      return renderFunction< MeshType, FunctionType, 1, 0, 3 >( parameters );
+      return renderFunction< MeshType, RealType, 1, 0, 3 >( parameters );
    if( xDiff == 1 && yDiff == 1 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 1, 1, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 1, 1, 0 >( parameters );
    if( xDiff == 1 && yDiff == 1 && zDiff == 1 )
-      return renderFunction< MeshType, FunctionType, 1, 1, 1 >( parameters );
+      return renderFunction< MeshType, RealType, 1, 1, 1 >( parameters );
    if( xDiff == 1 && yDiff == 1 && zDiff == 2 )
-      return renderFunction< MeshType, FunctionType, 1, 1, 2 >( parameters );
+      return renderFunction< MeshType, RealType, 1, 1, 2 >( parameters );
    if( xDiff == 1 && yDiff == 2 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 1, 2, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 1, 2, 0 >( parameters );
    if( xDiff == 1 && yDiff == 2 && zDiff == 1 )
-      return renderFunction< MeshType, FunctionType, 1, 2, 1 >( parameters );
+      return renderFunction< MeshType, RealType, 1, 2, 1 >( parameters );
    if( xDiff == 1 && yDiff == 3 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 1, 3, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 1, 3, 0 >( parameters );
    if( xDiff == 2 && yDiff == 0 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 2, 0, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 2, 0, 0 >( parameters );
    if( xDiff == 2 && yDiff == 0 && zDiff == 1 )
-      return renderFunction< MeshType, FunctionType, 2, 0, 1 >( parameters );
+      return renderFunction< MeshType, RealType, 2, 0, 1 >( parameters );
    if( xDiff == 2 && yDiff == 0 && zDiff == 2 )
-      return renderFunction< MeshType, FunctionType, 2, 0, 2 >( parameters );
+      return renderFunction< MeshType, RealType, 2, 0, 2 >( parameters );
    if( xDiff == 2 && yDiff == 1 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 2, 1, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 2, 1, 0 >( parameters );
    if( xDiff == 2 && yDiff == 1 && zDiff == 1 )
-      return renderFunction< MeshType, FunctionType, 2, 1, 1 >( parameters );
+      return renderFunction< MeshType, RealType, 2, 1, 1 >( parameters );
    if( xDiff == 2 && yDiff == 2 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 2, 2, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 2, 2, 0 >( parameters );
    if( xDiff == 3 && yDiff == 0 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 3, 0, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 3, 0, 0 >( parameters );
    if( xDiff == 3 && yDiff == 0 && zDiff == 1 )
-      return renderFunction< MeshType, FunctionType, 3, 0, 1 >( parameters );
+      return renderFunction< MeshType, RealType, 3, 0, 1 >( parameters );
    if( xDiff == 3 && yDiff == 1 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 3, 1, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 3, 1, 0 >( parameters );
    if( xDiff == 4 && yDiff == 0 && zDiff == 0 )
-      return renderFunction< MeshType, FunctionType, 4, 0, 0 >( parameters );
+      return renderFunction< MeshType, RealType, 4, 0, 0 >( parameters );
    return false;
 }
 
-
 template< typename MeshType >
-bool resolveFunction( const tnlParameterContainer& parameters )
+bool resolveRealType( const tnlParameterContainer& parameters )
 {
-   tnlString functionName = parameters.GetParameter< tnlString >( "function" );
-   cout << "+ -> Generating function " << functionName << " ... " << endl;
-   if( functionName == "sin-wave" )
-   {
-      typedef tnlSinWaveFunction< MeshType::Dimensions, typename MeshType::RealType > FunctionType;
-      return resolveDerivatives< MeshType, FunctionType >( parameters );
-   }
-   if( functionName == "sin-bumps" )
-   {
-      typedef tnlSinBumpsFunction< MeshType::Dimensions, typename MeshType::RealType > FunctionType;
-      return resolveDerivatives< MeshType, FunctionType >( parameters );
-   }
-   if( functionName == "exp-bump" )
-   {
-      typedef tnlExpBumpFunction< MeshType::Dimensions, typename MeshType::RealType > FunctionType;
-      return resolveDerivatives< MeshType, FunctionType >( parameters );
-   }
-   cerr << "Unknown function " << functionName << "." << endl;
-   return false;
+   tnlString realType = parameters.GetParameter< tnlString >( "real-type" );
+   if( realType == "mesh-real-type" )
+      return resolveDerivatives< MeshType, typename MeshType::RealType >( parameters );
+   if( realType == "float" )
+      return resolveDerivatives< MeshType, float >( parameters );
+   if( realType == "double" )
+      return resolveDerivatives< MeshType, double >( parameters );
+   if( realType == "long-double" )
+      return resolveDerivatives< MeshType, long double >( parameters );
 }
 
+
 template< int Dimensions, typename RealType, typename IndexType >
 bool resolveMesh( const tnlList< tnlString >& parsedMeshType,
                   const tnlParameterContainer& parameters )
@@ -191,7 +206,7 @@ bool resolveMesh( const tnlList< tnlString >& parsedMeshType,
    if( parsedMeshType[ 0 ] == "tnlGrid" )
    {
       typedef tnlGrid< Dimensions, RealType, tnlHost, IndexType > MeshType;
-      return resolveFunction< MeshType >( parameters );
+      return resolveRealType< MeshType >( parameters );
    }
    cerr << "Unknown mesh type." << endl;
    return false;
-- 
GitLab