Skip to content
Snippets Groups Projects
SemiImplicitTimeStepper_impl.h 7.46 KiB
Newer Older
/***************************************************************************
Tomáš Oberhuber's avatar
Tomáš Oberhuber committed
                          SemiImplicitTimeStepper_impl.h  -  description
                             -------------------
    begin                : Oct 4, 2014
    copyright            : (C) 2014 by Tomas Oberhuber
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/* See Copyright Notice in tnl/Copyright */
#pragma once
#include <TNL/Solvers/PDE/SemiImplicitTimeStepper.h>
#include <TNL/Solvers/LinearSolverTypeResolver.h>
namespace TNL {
Tomáš Oberhuber's avatar
Tomáš Oberhuber committed
namespace Solvers {
configSetup( Config::ConfigDescription& config,
             const String& prefix )
   config.addEntry< bool >( "verbose", "Verbose mode.", true );
setup( const Config::ParameterContainer& parameters,
   this->verbose = parameters.getParameter< bool >( "verbose" );

   // 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;
   }

init( const MeshPointer& mesh )
   if( ! this->problem->setupLinearSystem( this->matrix ) ) {
      std::cerr << "Failed to set up the linear system." << std::endl;
   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;
      if( ! this->matrix->getRows() )
         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;
   this->rightHandSidePointer->setSize( this->matrix.getData().getRows() );

   this->preIterateTimer.reset();
   this->linearSystemAssemblerTimer.reset();
   this->preconditionerUpdateTimer.reset();
   this->linearSystemSolverTimer.reset();
   this->postIterateTimer.reset();

   this->allIterations = 0;
setProblem( ProblemType& problem )
   this->problem = &problem;
getProblem() const
    return this->problem;
setSolverMonitor( SolverMonitorType& solverMonitor )
{
   this->solverMonitor = &solverMonitor;
   if( this->linearSystemSolver )
      this->linearSystemSolver->setSolverMonitor( solverMonitor );
}

setTimeStep( const RealType& timeStep )
   if( timeStep <= 0.0 )
Tomáš Oberhuber's avatar
Tomáš Oberhuber committed
      std::cerr << "Time step for SemiImplicitTimeStepper must be positive. " << std::endl;
   this->timeStep = timeStep;
solve( const RealType& time,
       const RealType& stopTime,
       DofVectorPointer& dofVector )
   TNL_ASSERT_TRUE( this->problem, "problem was not set" );
   this->linearSystemSolver->setMatrix( this->matrix );
   // 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,
                                           dofVector,
                                           this->matrix,
                                           this->rightHandSidePointer );
      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" );
      if( this->preconditioner )
      {
         this->preconditionerUpdateTimer.start();
         preconditioner->update( this->matrix );
      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 );
      this->linearSystemSolverTimer.stop();
      this->allIterations += this->linearSystemSolver->getIterations();
      //  std::cout << std::endl;
      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();

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 );
Tomáš Oberhuber's avatar
Tomáš Oberhuber committed
} // namespace PDE
} // namespace Solvers
} // namespace TNL