Newer
Older
/***************************************************************************
tnlTestFunction_impl.h - description
-------------------
begin : Aug 3, 2014
copyright : (C) 2014 by Tomas Oberhuber
email : tomas.oberhuber@fjfi.cvut.cz
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef TNLTESTFUNCTION_IMPL_H_
#define TNLTESTFUNCTION_IMPL_H_
#include <functors/tnlConstantFunction.h>
#include <functors/tnlExpBumpFunction.h>
#include <functors/tnlSinBumpsFunction.h>
#include <functors/tnlSinWaveFunction.h>
template< int FunctionDimensions,
typename Real,
typename Device >
tnlTestFunction< FunctionDimensions, Real, Device >::
tnlTestFunction()
timeDependence( none ),
timeScale( 1.0 )
template< int FunctionDimensions,
typename Real,
typename Device >
void
tnlTestFunction< FunctionDimensions, Real, Device >::
configSetup( tnlConfigDescription& config,
const tnlString& prefix )
{
config.addRequiredEntry< tnlString >( prefix + "test-function", "Testing function." );
config.addEntryEnum( "constant" );
config.addEntryEnum( "exp-bump" );
config.addEntryEnum( "sin-wave" );
config.addEntryEnum( "sin-bumps" );
config.addEntry < double >( prefix + "constant", "Value of the constant function.", 0.0 );
config.addEntry < double >( prefix + "wave-length", "Wave length of the sine based test functions.", 1.0 );
config.addEntry < double >( prefix + "wave-length-x", "Wave length of the sine based test functions.", 1.0 );
config.addEntry < double >( prefix + "wave-length-y", "Wave length of the sine based test functions.", 1.0 );
config.addEntry < double >( prefix + "wave-length-z", "Wave length of the sine based test functions.", 1.0 );
config.addEntry < double >( prefix + "phase", "Phase of the sine based test functions.", 0.0 );
config.addEntry < double >( prefix + "phase-x", "Phase of the sine based test functions.", 0.0 );
config.addEntry < double >( prefix + "phase-y", "Phase of the sine based test functions.", 0.0 );
config.addEntry < double >( prefix + "phase-z", "Phase of the sine based test functions.", 0.0 );
config.addEntry < double >( prefix + "amplitude", "Amplitude length of the sine based test functions.", 1.0 );
config.addEntry < double >( prefix + "waves-number", "Cut-off for the sine based test functions.", 0.0 );
config.addEntry < double >( prefix + "waves-number-x", "Cut-off for the sine based test functions.", 0.0 );
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 >( prefix + "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 dependency of the test function.", 1.0 );
template< int FunctionDimensions,
typename Real,
typename Device >
tnlTestFunction< FunctionDimensions, Real, Device >::
setupFunction( const tnlParameterContainer& parameters,
const tnlString& prefix )
{
FunctionType* auxFunction = new FunctionType;
if( ! auxFunction->setup( parameters, prefix ) )
{
delete auxFunction;
return false;
}
if( Device::DeviceType == ( int ) tnlHostDevice )
if( Device::DeviceType == ( int ) tnlCudaDevice )
this->function = tnlCuda::passToDevice( *auxFunction );
if( ! checkCudaDevice )
return false;
}
template< int FunctionDimensions,
typename Real,
typename Device >
bool
tnlTestFunction< FunctionDimensions, Real, Device >::
setup( const tnlParameterContainer& parameters,
cout << "Test function setup ... " << endl;
const tnlString& timeDependence =
parameters.getParameter< tnlString >(
cout << "Time dependence ... " << timeDependence << endl;
if( timeDependence == "none" )
this->timeDependence = none;
if( timeDependence == "linear" )
this->timeDependence = linear;
if( timeDependence == "quadratic" )
this->timeDependence = quadratic;
if( timeDependence == "cosine" )
this->timeDependence = cosine;
this->timeScale = parameters.getParameter< double >( prefix + "time-scale" );
const tnlString& testFunction = parameters.getParameter< tnlString >( prefix + "test-function" );
cout << "Test function ... " << testFunction << endl;
if( testFunction == "constant" )
{
typedef tnlConstantFunction< Dimensions, Real > FunctionType;
functionType = constant;
return setupFunction< FunctionType >( parameters );
}
if( testFunction == "exp-bump" )
{
typedef tnlExpBumpFunction< Dimensions, Real > FunctionType;
functionType = expBump;
return setupFunction< FunctionType >( parameters );
}
if( testFunction == "sin-bumps" )
{
typedef tnlSinBumpsFunction< Dimensions, Real > FunctionType;
functionType = sinBumps;
return setupFunction< FunctionType >( parameters );
typedef tnlSinWaveFunction< Dimensions, Real > FunctionType;
functionType = sinWave;
return setupFunction< FunctionType >( parameters );
cerr << "Unknown function " << testFunction << endl;
return false;
template< int FunctionDimensions,
typename Real,
typename Device >
const tnlTestFunction< FunctionDimensions, Real, Device >&
tnlTestFunction< FunctionDimensions, Real, Device >::
operator = ( const tnlTestFunction& function )
/*****
* TODO: if the function is on the device we cannot do the following
*/
abort();
this->functionType = function.functionType;
this->timeDependence = function.timeDependence;
this->timeScale = function.timeScale;
switch( this->functionType )
case constant:
this->copyFunction< tnlConstantFunction< FunctionDimensions, Real > >( function.function );
break;
case expBump:
this->copyFunction< tnlExpBumpFunction< FunctionDimensions, Real > >( function.function );
break;
case sinBumps:
this->copyFunction< tnlSinBumpsFunction< FunctionDimensions, Real > >( function.function );
break;
case sinWave:
this->copyFunction< tnlSinWaveFunction< FunctionDimensions, Real > >( function.function );
break;
default:
tnlAssert( false, );
break;
template< int FunctionDimensions,
typename Real,
typename Device >
template< int XDiffOrder,
int YDiffOrder,
int ZDiffOrder,
typename Vertex >
Real
tnlTestFunction< FunctionDimensions, Real, Device >::
getValue( const Vertex& vertex,
const Real& time ) const
{
Real scale( 1.0 );
switch( this->timeDependence )
{
case none:
break;
case linear:
scale = 1.0 - this->timeScale * time;
break;
case quadratic:
scale = this->timeScale * time;
scale *= scale;
scale = 1.0 - scale;
break;
case cosine:
scale = cos( this->timeScale * time );
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
break;
}
switch( functionType )
{
case constant:
return scale * ( ( tnlConstantFunction< Dimensions, Real >* ) function )->
getValue< XDiffOrder, YDiffOrder, ZDiffOrder, Vertex >( vertex, time );
case expBump:
return scale * ( ( tnlExpBumpFunction< Dimensions, Real >* ) function )->
getValue< XDiffOrder, YDiffOrder, ZDiffOrder, Vertex >( vertex, time );
case sinBumps:
return scale * ( ( tnlSinBumpsFunction< Dimensions, Real >* ) function )->
getValue< XDiffOrder, YDiffOrder, ZDiffOrder, Vertex >( vertex, time );
case sinWave:
return scale * ( ( tnlSinWaveFunction< Dimensions, Real >* ) function )->
getValue< XDiffOrder, YDiffOrder, ZDiffOrder, Vertex >( vertex, time );
default:
return 0.0;
}
}
template< int FunctionDimensions,
typename Real,
typename Device >
template< int XDiffOrder,
int YDiffOrder,
int ZDiffOrder,
typename Vertex >
Real
tnlTestFunction< FunctionDimensions, Real, Device >::
getTimeDerivative( const Vertex& vertex,
const Real& time ) const
Real scale( 0.0 );
switch( timeDependence )
{
case none:
break;
case linear:
scale = -this->timeScale;
break;
case quadratic:
scale = -2.0 * this->timeScale * this->timeScale * time;
break;
case cosine:
scale = -this->timeScale * sin( this->timeScale * time );
switch( functionType )
{
case constant:
return scale * ( ( tnlConstantFunction< Dimensions, Real >* ) function )->
getValue< XDiffOrder, YDiffOrder, ZDiffOrder, Vertex >( vertex, time );
return scale * ( ( tnlExpBumpFunction< Dimensions, Real >* ) function )->
getValue< XDiffOrder, YDiffOrder, ZDiffOrder, Vertex >( vertex, time );
return scale * ( ( tnlSinBumpsFunction< Dimensions, Real >* ) function )->
getValue< XDiffOrder, YDiffOrder, ZDiffOrder, Vertex >( vertex, time );
return scale * ( ( tnlSinWaveFunction< Dimensions, Real >* ) function )->
getValue< XDiffOrder, YDiffOrder, ZDiffOrder, Vertex >( vertex, time );
}
}
template< int FunctionDimensions,
typename Real,
typename Device >
template< typename FunctionType >
void
tnlTestFunction< FunctionDimensions, Real, Device >::
deleteFunction()
{
if( Device::DeviceType == ( int ) tnlHostDevice )
{
if( function )
delete ( FunctionType * ) function;
}
if( Device::DeviceType == ( int ) tnlCudaDevice )
{
if( function )
tnlCuda::freeFromDevice( ( FunctionType * ) function );
}
}
template< int FunctionDimensions,
typename Real,
typename Device >
tnlTestFunction< FunctionDimensions, Real, Device >::
case constant:
deleteFunction< tnlConstantFunction< Dimensions, Real> >();
break;
case expBump:
deleteFunction< tnlExpBumpFunction< Dimensions, Real> >();
break;
case sinBumps:
deleteFunction< tnlSinBumpsFunction< Dimensions, Real> >();
break;
case sinWave:
deleteFunction< tnlSinWaveFunction< Dimensions, Real> >();
break;
template< int FunctionDimensions,
typename Real,
typename Device >
template< typename FunctionType >
void
tnlTestFunction< FunctionDimensions, Real, Device >::
copyFunction( const void* function )
{
if( Device::DeviceType == ( int ) tnlHostDevice )
{
FunctionType* f = new FunctionType;
*f = * ( FunctionType* )function;
}
if( Device::DeviceType == ( int ) tnlCudaDevice )
{
tnlAssert( false, );
abort();
}
}
template< int FunctionDimensions,
typename Real,
typename Device >
template< typename FunctionType >
ostream&
tnlTestFunction< FunctionDimensions, Real, Device >::
printFunction( ostream& str ) const
{
FunctionType* f = ( FunctionType* ) this->function;
switch( Device::DeviceType )
case tnlHostDevice:
str << *f;
return str;
case tnlCudaDevice:
tnlCuda::print( f, str );
return str;
default:
return str;
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
}
}
template< int FunctionDimensions,
typename Real,
typename Device >
ostream&
tnlTestFunction< FunctionDimensions, Real, Device >::
print( ostream& str ) const
{
str << " timeDependence = " << this->timeDependence;
str << " functionType = " << this->functionType;
str << " function = " << this->function << "; ";
switch( functionType )
{
case constant:
return printFunction< tnlConstantFunction< Dimensions, Real> >( str );
case expBump:
return printFunction< tnlExpBumpFunction< Dimensions, Real> >( str );
case sinBumps:
return printFunction< tnlSinBumpsFunction< Dimensions, Real> >( str );
case sinWave:
return printFunction< tnlSinWaveFunction< Dimensions, Real> >( str );
}
return str;
}
template< int FunctionDimensions,
typename Real,
typename Device >
tnlTestFunction< FunctionDimensions, Real, Device >::
~tnlTestFunction()
{
deleteFunctions();
}
#ifdef INSTANTIATE_FLOAT
extern template class tnlTestFunction< 1, float, tnlHost >;
extern template class tnlTestFunction< 2, float, tnlHost >;
extern template class tnlTestFunction< 3, float, tnlHost >;
extern template class tnlTestFunction< 1, double, tnlHost >;
extern template class tnlTestFunction< 2, double, tnlHost >;
extern template class tnlTestFunction< 3, double, tnlHost >;
#ifdef INSTANTIATE_LONG_DOUBLE
extern template class tnlTestFunction< 1, long double, tnlHost >;
extern template class tnlTestFunction< 2, long double, tnlHost >;
extern template class tnlTestFunction< 3, long double, tnlHost >;
#ifdef INSTANTIATE_FLOAT
extern template class tnlTestFunction< 1, float, tnlCuda>;
extern template class tnlTestFunction< 2, float, tnlCuda >;
extern template class tnlTestFunction< 3, float, tnlCuda >;
extern template class tnlTestFunction< 1, double, tnlCuda >;
extern template class tnlTestFunction< 2, double, tnlCuda >;
extern template class tnlTestFunction< 3, double, tnlCuda >;
#ifdef INSTANTIATE_LONG_DOUBLE
extern template class tnlTestFunction< 1, long double, tnlCuda >;
extern template class tnlTestFunction< 2, long double, tnlCuda >;
extern template class tnlTestFunction< 3, long double, tnlCuda >;
#endif
#endif /* TNLTESTFUNCTION_IMPL_H_ */