LifeV
TimeIterationPolicyNonlinear.hpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file TimeIterationNonlinear class
29  @brief This class contains all the informations necessary
30  to perform a time iteration
31 
32  @author Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
33  @date 06-12-2012
34  */
35 
36 #ifndef TIMEITERATIONPOLICYNONLINEAR_HPP
37 #define TIMEITERATIONPOLICYNONLINEAR_HPP
38 
39 #include <iostream>
40 #include <string>
41 #include <boost/shared_ptr.hpp>
42 
43 
44 #ifdef HAVE_MPI
45 #include <Epetra_MpiComm.h>
46 #else
47 #include <Epetra_SerialComm.h>
48 #endif
49 
50 #include <Teuchos_ParameterList.hpp>
51 #include <Teuchos_XMLParameterListHelpers.hpp>
52 #include <Teuchos_RCP.hpp>
53 
54 
55 #include <lifev/core/LifeV.hpp>
56 #include <lifev/core/array/MatrixEpetra.hpp>
57 #include <lifev/core/array/VectorEpetra.hpp>
58 #include <lifev/core/util/Displayer.hpp>
59 #include <lifev/core/util/LifeChrono.hpp>
60 #include <lifev/core/mesh/RegionMesh.hpp>
61 #include <lifev/core/fem/FESpace.hpp>
62 #include <lifev/core/fem/TimeAdvanceBDF.hpp>
63 #include <lifev/core/fem/BCHandler.hpp>
64 #include <lifev/navier_stokes/solver/NavierStokesSolver/SolverPolicyLinearSolver.hpp>
65 
66 
67 namespace LifeV
68 {
69 
70 template< class mesh_Type, class AssemblyPolicy, class SolverPolicy = SolverPolicyLinearSolver >
71 struct TimeIterationPolicyNonlinear : private AssemblyPolicy, public virtual SolverPolicy
72 {
73 protected:
78  typedef MeshPartitioner< mesh_Type > meshPartitioner_Type;
81  typedef FESpace< mesh_Type, map_Type > fespace_Type;
83  typedef TimeAdvanceBDF<vector_Type> bdf_Type;
87 
88  enum { BDFOrder = AssemblyPolicy::BDFOrder };
89 
90  void initTimeIteration ( Teuchos::ParameterList& list );
91 
92  void iterate ( vectorPtr_Type solution,
93  bcContainerPtr_Type bchandler,
94  const Real& currentTime );
95 
96  // Parameters
99 
103 
104  virtual Displayer displayer() = 0;
105  virtual fespacePtr_Type uFESpace() const = 0;
106  virtual fespacePtr_Type pFESpace() const = 0;
107 };
108 
109 template< class mesh_Type, class AssemblyPolicy, class SolverPolicy >
110 void
111 TimeIterationPolicyNonlinear<mesh_Type, AssemblyPolicy, SolverPolicy>::
112 initTimeIteration ( Teuchos::ParameterList& list )
113 {
114  // Parameters
115  M_computeResidual = list.get ( "Compute exact residual", false );
116  M_nonLinearTolerance = list.get ( "Nonlinear tolerance", 1e-6 );
117 
118  // Initialization
119  M_solutionMap.reset ( new map_Type ( uFESpace()->map() + pFESpace()->map() ) );
120 
121  // Init the assembler
122  Teuchos::ParameterList assemblyList = list.sublist ( "Assembly: Parameter list" );
123  AssemblyPolicy::initAssembly ( assemblyList );
124 
125  // Init the solver
126  Teuchos::ParameterList solverList = list.sublist ( "Solver: Parameter list" );
127  SolverPolicy::initSolver ( solverList );
128  M_rhs.reset ( new vector_Type ( *M_solutionMap, Unique ) );
129 }
130 
131 template< class mesh_Type, class AssemblyPolicy, class SolverPolicy >
132 void
133 TimeIterationPolicyNonlinear<mesh_Type, AssemblyPolicy, SolverPolicy>::
135  bcContainerPtr_Type bchandler,
136  const Real& currentTime )
137 {
138  int subiter = 0;
139 
140  Real normRhs ( 0.0 );
141  Real nonLinearResidual ( 0.0 );
142  Real rhsIterNorm ( 0.0 );
143 
144  do
145  {
146  //
147  // STEP 1: Updating the system
148  //
149  displayer().leaderPrint ( "Updating the system... " );
150  *M_rhs = 0.0;
151  M_systemMatrix.reset ( new matrix_Type ( *M_solutionMap ) );
152  AssemblyPolicy::assembleSystem ( M_systemMatrix, M_rhs, solution, SolverPolicy::preconditioner() );
153  displayer().leaderPrint ( "done\n" );
154 
155  //
156  // STEP 2: Applying the boundary conditions
157  //
158  displayer().leaderPrint ( "Applying BC... " );
159  bcManage ( *M_systemMatrix, *M_rhs, *uFESpace()->mesh(), uFESpace()->dof(), *bchandler, uFESpace()->feBd(), 1.0, currentTime );
160  M_systemMatrix->globalAssemble();
161  displayer().leaderPrint ( "done\n" );
162 
163  // Norm of the rhs needed for the nonlinear convergence test
164  if ( subiter == 0 )
165  {
166  normRhs = M_rhs->norm2();
167  }
168 
169  //
170  // STEP 3: Computing the residual
171  //
172 
173  // Computing the RHS as RHS=b-Ax_k
174  vector_Type Ax ( solution->map() );
175  M_systemMatrix->matrixPtr()->Apply ( solution->epetraVector(), Ax.epetraVector() );
176 
177  Ax.epetraVector().Update (-1, M_rhs->epetraVector(), 1);
178  nonLinearResidual = Ax.norm2();
179 
180  displayer().leaderPrint ( "Nonlinear residual : ", nonLinearResidual, "\n" );
181  displayer().leaderPrint ( "Nonlinear residual (scaled) : ", nonLinearResidual / normRhs, "\n" );
182 
183  if ( nonLinearResidual > M_nonLinearTolerance * normRhs )
184  {
185  displayer().leaderPrint ( "---\nSubiteration [", ++subiter, "]\n" );
186 
187  // Extra information if we want to know the exact residual
188  if ( M_computeResidual )
189  {
190  rhsIterNorm = M_rhs->norm2();
191  }
192 
193  //
194  // Solving the system
195  //
196  displayer().leaderPrint ( "Solving the system... \n" );
197  *solution = 0.0;
198  SolverPolicy::solve ( M_systemMatrix, M_rhs, solution );
199  // int numIter = SolverPolicy::solve( M_systemMatrix, M_rhs, solution );
200  // numIterSum += numIter; //
201 
202  if ( M_computeResidual )
203  {
204  vector_Type Ax ( solution->map() );
205  vector_Type res ( *M_rhs );
206  M_systemMatrix->matrixPtr()->Apply ( solution->epetraVector(), Ax.epetraVector() );
207  res.epetraVector().Update ( -1, Ax.epetraVector(), 1 );
208  Real residual;
209  res.norm2 ( &residual );
210  residual /= rhsIterNorm;
211  displayer().leaderPrint ( "Scaled residual: ", residual, "\n" );
212  }
213  }
214  }
215  while ( nonLinearResidual > M_nonLinearTolerance * normRhs );
216 
217  displayer().leaderPrint ( "Nonlinear iterations : ", subiter, "\n" );
218 }
219 
220 } // namespace LifeV
221 
222 #endif /* TIMEITERATIONPOLICYNONLINEAR_HPP */
VectorEpetra - The Epetra Vector format Wrapper.
virtual fespacePtr_Type pFESpace() const =0
void importFromHDF5(std::string const &fileName, std::string const &matrixName="matrix")
Read a matrix from a HDF5 (.h5) file.
BCHandler - class for handling boundary conditions.
Definition: BCHandler.hpp:100
void updateInverseJacobian(const UInt &iQuadPt)
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
virtual Displayer displayer()=0
void norm2(Real *result) const
Compute and store the norm 2 in the given pointed variable.
std::shared_ptr< fespace_Type > fespacePtr_Type
virtual fespacePtr_Type uFESpace() const =0
double Real
Generic real data.
Definition: LifeV.hpp:175
void iterate(vectorPtr_Type solution, bcContainerPtr_Type bchandler, const Real &currentTime)
std::shared_ptr< VectorEpetra > vectorPtr_Type
std::shared_ptr< bcContainer_Type > bcContainerPtr_Type
Displayer - This class is used to display messages in parallel simulations.
Definition: Displayer.hpp:62
void initTimeIteration(Teuchos::ParameterList &list)
Real norm2() const
Compute and return the norm 2.