Wiki

Clone wiki

lifev-release / tutorial / Linear_solver

Go back


Linear solver

In this section of the tutorial we provide examples on how to solve the linear system arising from the finite elements discretization of the PDE problem. To this aim, we suppose the finite elements matrix A and the right hand side f are available.

In the following we will employ the LinearSolver class. This class is a common interface for the iterative solvers distributed within the Trilinos project, AtzecOO and Belos, where different iterative methods are currently available and should be chosen according to the problem we are dealing with: CG, Block CG, Block GMRES, Block Flexible GMRES, etc.

We can devise the following steps to reach an approximate solution of the linear system by an iterative method:

Set the solver data

In order to set the data for the iterative solver, we take advantage of the .xml datafile format where all the options to be used in the solution phase are specified.

Here is an example of .xml datafile:

    <ParameterList>
            <!-- LinearSolver parameters -->
            <Parameter name="Reuse Preconditioner" type="bool" value="false"/>
            <Parameter name="Max Iterations For Reuse" type="int" value="80"/>
            <Parameter name="Quit On Failure" type="bool" value="false"/>
            <Parameter name="Silent" type="bool" value="false"/>
        <Parameter name="Solver Type" type="string" value="AztecOO"/>

        <!-- Operator specific parameters (AztecOO) -->
        <ParameterList name="Solver: Operator List">

            <!-- Trilinos parameters -->
            <ParameterList name="Trilinos: AztecOO List">
                <Parameter name="solver" type="string" value="gmres"/>
                <Parameter name="conv" type="string" value="rhs"/>
                <Parameter name="scaling" type="string" value="none"/>
                <Parameter name="output" type="string" value="all"/>
                <Parameter name="tol" type="double" value="1.e-12"/>
                <Parameter name="max_iter" type="int" value="200"/>
                <Parameter name="kspace" type="int" value="100"/>
                <Parameter name="orthog" type="int" value="0"/>
                <Parameter name="aux_vec" type="int" value="0"/>
            </ParameterList>
        </ParameterList>
    </ParameterList>

The .xml datafile format allows to build a genealogy tree of subparameter lists, for example the parent list ParameterList details the generic options: "Reuse Preconditioner", "Max Iterations For Reuse", "Quit On Failure", "Silent" and "Solver Type". Then it is followed by a parameter sublist "Trilinos: AztecOO List" where the parameters specific for the AztecOO iterative class are given.

In order to read a .xml datafile in LifeV, we employ the Trilinos class Teuchos::ParameterList, by using the following commands:

    Teuchos::RCP< Teuchos::ParameterList > solverParameterList = Teuchos::rcp ( new Teuchos::ParameterList );
    solverParameterList = Teuchos::getParametersFromXmlFile ( "xmlFileExample.xml" );

If we want to extract information from the parameter list or manually set the parameters we can use the following methods:

    solverParameterList->print ( std::cout );   // print on the screen the whole parameter list
    solverParameterList->get("<paramter to be returned>" );   // return a parameter value
    solverParameterList->set("<paramter to be set>", <value> );   // set a parameter value

Here you can download the mainXML.cpp file.

Set the preconditioner data

When dealing with large-scale simulations, it is essential to rely on preconditioning technique in order to enhance the convergence of the linear solver. In LifeV, several preconditioners are available. The class LifeV::PreconditionerIfpack wraps the IfpackPreconditioner class of Trilinos and contains one-level type preconditioner (Additive Schwarz, Block Gauss-Seidel, Block Jacobi, ILU, ...); for multilevel preconditioners, the LifeV::PreconditionerML wraps the preconditioners implemented in ML Trilinos package.

In the following, we will see how to set up a one-level Additive Schwarz preconditioner, setting the data from a GetPot variable.

    typedef LifeV::Preconditioner               basePrec_Type;
    typedef std::shared_ptr<basePrec_Type>    basePrecPtr_Type;
    typedef LifeV::PreconditionerIfpack         prec_Type;
    typedef std::shared_ptr<prec_Type>        precPtr_Type;

    prec_Type* precRawPtr;
    basePrecPtr_Type preconditionerPtr;
    precRawPtr = new prec_Type;
    precRawPtr->setDataFromGetPot ( dataFile, "prec" );    // setting data from GetPot, "prec" is the location of the data for the preconditioner in the GetPot file
    preconditionerPtr.reset ( precRawPtr );

Here you can download an example of preconditioner data to be added to your GetPot file: preconditionerData.in.

Solve the linear system

Finally, in order to solve the linear system, we can use the following commands:

    std::shared_ptr<LifeV::MatrixEpetra<LifeV::Real>> Ah;
    std::shared_ptr<LifeV::VectorEpetra> fh, uh;

    // allocate Ah, fh, and uh and fill the matrix Ah and the RHS fh.

    LifeV::LinearSolver linearSolver ( CommunicatorPtr );            // create an instance of the LinearSolver
    linearSolver.setOperator ( Ah );                                 // set the stiffness matrix
    linearSolver.setRightHandSide( fh );                             // set the RHS
    linearSolver.setParameters ( *solverParameterList );             // set the parameter list
    linearSolver.setPreconditioner ( preconditionerPtr );            // set the preconditioner
    linearSolver.setTolerance ( tol );                               // set the target tolerance
    linearSolver.solve( uh );                                        // solve the linear system

Updated