/*************************************************************************** tnlSemiImplicitTimeStepper_impl.h - description ------------------- begin : Oct 4, 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 TNLSEMIIMPLICITTIMESTEPPER_IMPL_H_ #define TNLSEMIIMPLICITTIMESTEPPER_IMPL_H_ #include <core/mfuncs.h> template< typename Problem, typename LinearSystemSolver > tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver >:: tnlSemiImplicitTimeStepper() : problem( 0 ), linearSystemSolver( 0 ), timeStep( 0 ) { }; template< typename Problem, typename LinearSystemSolver > void tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver >:: configSetup( tnlConfigDescription& config, const tnlString& prefix ) { config.addEntry< bool >( "verbose", "Verbose mode.", true ); } template< typename Problem, typename LinearSystemSolver > bool tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver >:: setup( const tnlParameterContainer& parameters, const tnlString& prefix ) { this->verbose = parameters.GetParameter< bool >( "verbose" ); return true; } template< typename Problem, typename LinearSystemSolver > bool tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver >:: init( const MeshType& mesh ) { if( ! this->problem->setupLinearSystem( mesh, this->matrix ) ) return false; if( this->matrix.getRows() == 0 || this->matrix.getColumns() == 0 ) { cerr << "The matrix for the semi-implicit time stepping was not set correctly." << endl; if( ! this->matrix.getRows() ) cerr << "The matrix dimensions are set to 0 rows." << endl; if( ! this->matrix.getColumns() ) cerr << "The matrix dimensions are set to 0 columns." << endl; cerr << "Please check the method 'setupLinearSystem' in your solver." << endl; return false; } if( ! this->rightHandSide.setSize( this->matrix.getRows() ) ) return false; return true; } template< typename Problem, typename LinearSystemSolver > void tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver >:: setProblem( ProblemType& problem ) { this -> problem = &problem; }; template< typename Problem, typename LinearSystemSolver > Problem* tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver >:: getProblem() const { return this -> problem; }; template< typename Problem, typename LinearSystemSolver > void tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver >:: setSolver( LinearSystemSolver& linearSystemSolver ) { this->linearSystemSolver = &linearSystemSolver; } template< typename Problem, typename LinearSystemSolver > LinearSystemSolver* tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver >:: getSolver() const { return this->linearSystemSolver; } template< typename Problem, typename LinearSystemSolver > bool tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver >:: setTimeStep( const RealType& timeStep ) { if( timeStep <= 0.0 ) { cerr << "Time step for tnlSemiImplicitTimeStepper must be positive. " << endl; return false; } this->timeStep = timeStep; }; template< typename Problem, typename LinearSystemSolver > bool tnlSemiImplicitTimeStepper< Problem, LinearSystemSolver >:: solve( const RealType& time, const RealType& stopTime, const MeshType& mesh, DofVectorType& dofVector ) { tnlAssert( this->problem != 0, ); RealType t = time; this->linearSystemSolver->setMatrix( this->matrix ); while( t < stopTime ) { RealType currentTau = Min( this->timeStep, stopTime - t ); if( ! this->problem->preIterate( t, currentTau, mesh, dofVector ) ) { cerr << endl << "Preiteration failed." << endl; return false; } if( verbose ) cout << " Assembling the linear system ... \r" << flush; this->problem->assemblyLinearSystem( t, currentTau, mesh, dofVector, this->matrix, this->rightHandSide ); if( verbose ) cout << " Solving the linear system for time " << t << " \r" << flush; if( ! this->linearSystemSolver->solve( this->rightHandSide, dofVector ) ) { cerr << "The linear system solver did not converge." << endl; return false; } if( ! this->problem->postIterate( t, currentTau, mesh, dofVector ) ) { cerr << endl << "Postiteration failed." << endl; return false; } t += currentTau; } return true; } #endif /* TNLSEMIIMPLICITTIMESTEPPER_IMPL_H_ */