Newer
Older
/***************************************************************************
-------------------
begin : Oct 4, 2014
copyright : (C) 2014 by Tomas Oberhuber
email : tomas.oberhuber@fjfi.cvut.cz
***************************************************************************/
/* See Copyright Notice in tnl/Copyright */
#include <TNL/Math.h>
#include <TNL/Solvers/PDE/SemiImplicitTimeStepper.h>
Jakub Klinkovský
committed
#include <TNL/Solvers/LinearSolverTypeResolver.h>
Jakub Klinkovský
committed
namespace PDE {
Jakub Klinkovský
committed
template< typename Problem >
Jakub Klinkovský
committed
SemiImplicitTimeStepper< Problem >::
configSetup( Config::ConfigDescription& config,
const String& prefix )
config.addEntry< bool >( "verbose", "Verbose mode.", true );
Jakub Klinkovský
committed
template< typename Problem >
Jakub Klinkovský
committed
SemiImplicitTimeStepper< Problem >::
setup( const Config::ParameterContainer& parameters,
Jakub Klinkovský
committed
const String& prefix )
this->verbose = parameters.getParameter< bool >( "verbose" );
Jakub Klinkovský
committed
// set up the linear solver
linearSystemSolver = getLinearSolver< MatrixType >( parameters );
if( ! linearSystemSolver )
return false;
if( ! linearSystemSolver->setup( parameters ) )
return false;
// set up the preconditioner
preconditioner = getPreconditioner< MatrixType >( parameters );
if( preconditioner ) {
linearSystemSolver->setPreconditioner( preconditioner );
if( ! preconditioner->setup( parameters ) )
return false;
}
Jakub Klinkovský
committed
template< typename Problem >
Jakub Klinkovský
committed
SemiImplicitTimeStepper< Problem >::
if( ! this->problem->setupLinearSystem( this->matrix ) ) {
std::cerr << "Failed to set up the linear system." << std::endl;
return false;
if( this->matrix.getData().getRows() == 0 || this->matrix.getData().getColumns() == 0 )
std::cerr << "The matrix for the semi-implicit time stepping was not set correctly." << std::endl;
std::cerr << "The matrix dimensions are set to 0 rows." << std::endl;
if( ! this->matrix->getColumns() )
std::cerr << "The matrix dimensions are set to 0 columns." << std::endl;
std::cerr << "Please check the method 'setupLinearSystem' in your solver." << std::endl;
return false;
}
Jakub Klinkovský
committed
this->rightHandSidePointer->setSize( this->matrix.getData().getRows() );
this->linearSystemAssemblerTimer.reset();
this->preconditionerUpdateTimer.reset();
this->linearSystemSolverTimer.reset();
return true;
Jakub Klinkovský
committed
template< typename Problem >
Jakub Klinkovský
committed
SemiImplicitTimeStepper< Problem >::
setProblem( ProblemType& problem )
Jakub Klinkovský
committed
template< typename Problem >
Jakub Klinkovský
committed
SemiImplicitTimeStepper< Problem >::
Jakub Klinkovský
committed
template< typename Problem >
Jakub Klinkovský
committed
SemiImplicitTimeStepper< Problem >::
setSolverMonitor( SolverMonitorType& solverMonitor )
{
this->solverMonitor = &solverMonitor;
if( this->linearSystemSolver )
this->linearSystemSolver->setSolverMonitor( solverMonitor );
}
Jakub Klinkovský
committed
template< typename Problem >
Jakub Klinkovský
committed
SemiImplicitTimeStepper< Problem >::
setTimeStep( const RealType& timeStep )
std::cerr << "Time step for SemiImplicitTimeStepper must be positive. " << std::endl;
this->timeStep = timeStep;
Jakub Klinkovský
committed
template< typename Problem >
Jakub Klinkovský
committed
SemiImplicitTimeStepper< Problem >::
solve( const RealType& time,
const RealType& stopTime,
TNL_ASSERT_TRUE( this->problem, "problem was not set" );
Jakub Klinkovský
committed
// set the matrix for the linear solver
this->linearSystemSolver->setMatrix( this->matrix );
Jakub Klinkovský
committed
RealType t = time;
// ignore very small steps at the end, most likely caused by truncation errors
while( stopTime - t > this->timeStep * 1e-6 )
RealType currentTau = min( this->timeStep, stopTime - t );
if( this->solverMonitor ) {
this->solverMonitor->setTime( t );
this->solverMonitor->setStage( "Preiteration" );
}
this->preIterateTimer.start();
if( ! this->problem->preIterate( t, currentTau, dofVector ) )
std::cerr << std::endl << "Preiteration failed." << std::endl;
this->preIterateTimer.stop();
// if( verbose )
// std::cout << " Assembling the linear system ... \r" << std::flush;
if( this->solverMonitor )
this->solverMonitor->setStage( "Assembling the linear system" );
this->linearSystemAssemblerTimer.start();
this->problem->assemblyLinearSystem( t,
currentTau,
this->linearSystemAssemblerTimer.stop();
// if( verbose )
// std::cout << " Solving the linear system for time " << t + currentTau << " \r" << std::flush;
if( this->solverMonitor )
this->solverMonitor->setStage( "Solving the linear system" );
Jakub Klinkovský
committed
if( this->preconditioner )
{
this->preconditionerUpdateTimer.start();
preconditioner->update( this->matrix );
Jakub Klinkovský
committed
this->preconditionerUpdateTimer.stop();
}
this->linearSystemSolverTimer.start();
if( ! this->linearSystemSolver->solve( *this->rightHandSidePointer, *dofVector ) )
std::cerr << std::endl << "The linear system solver did not converge." << std::endl;
// save the linear system for debugging
this->problem->saveFailedLinearSystem( *this->matrix, *dofVector, *this->rightHandSidePointer );
return false;
}
this->linearSystemSolverTimer.stop();
this->allIterations += this->linearSystemSolver->getIterations();
if( this->solverMonitor )
this->solverMonitor->setStage( "Postiteration" );
this->postIterateTimer.start();
if( ! this->problem->postIterate( t, currentTau, dofVector ) )
std::cerr << std::endl << "Postiteration failed." << std::endl;
this->postIterateTimer.stop();
return true;
Jakub Klinkovský
committed
template< typename Problem >
Jakub Klinkovský
committed
SemiImplicitTimeStepper< Problem >::
writeEpilog( Logger& logger ) const
logger.writeParameter< long long int >( "Iterations count:", this->allIterations );
logger.writeParameter< const char* >( "Pre-iterate time:", "" );
this->preIterateTimer.writeLog( logger, 1 );
logger.writeParameter< const char* >( "Linear system assembler time:", "" );
this->linearSystemAssemblerTimer.writeLog( logger, 1 );
logger.writeParameter< const char* >( "Preconditioner update time:", "" );
this->preconditionerUpdateTimer.writeLog( logger, 1 );
logger.writeParameter< const char* >( "Linear system solver time:", "" );
this->linearSystemSolverTimer.writeLog( logger, 1 );
logger.writeParameter< const char* >( "Post-iterate time:", "" );
this->postIterateTimer.writeLog( logger, 1 );