LifeV
PreconditionerYosida.cpp
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
29  @brief PreconditionerYosida
30 
31  @author Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
32  @maintainer Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
33 
34  @date 13-10-2011
35  */
36 
37 #include <vector>
39 #include <lifev/core/algorithm/PreconditionerIfpack.hpp>
40 #include <lifev/core/algorithm/PreconditionerML.hpp>
41 // #include <lifev/core/algorithm/PreconditionerML2.hpp>
42 #include <lifev/core/util/LifeChrono.hpp>
43 #include <lifev/core/array/MatrixEpetraStructured.hpp>
44 #include <lifev/core/array/MatrixEpetraStructuredView.hpp>
45 #include <lifev/core/array/MatrixEpetraStructuredUtility.hpp>
46 
47 namespace LifeV
48 {
49 
50 PreconditionerYosida::PreconditionerYosida ( const std::shared_ptr<Epetra_Comm>& comm ) :
52  M_velocityBlockSize ( -1 ),
53  M_pressureBlockSize ( -1 ),
54  M_timestep ( 1.0 )
55 {
56 
57  M_uFESpace.reset();
58  M_pFESpace.reset();
59 
60 }
61 
63 {
64 
65 }
66 
67 void
69  const GetPot& dataFile,
70  const std::string& section,
71  const std::string& subsection )
72 {
73  const bool verbose ( M_comm->MyPID() == 0 );
74 
75  bool displayList = dataFile ( ( section + "/displayList" ).data(), false);
76 
77  std::string precType = dataFile ( ( section + "/prectype" ).data(), "Yosida" );
78  list.set ( "prectype", precType );
79 
80  std::string fluidPrec = dataFile ( ( section + "/" + subsection + "/subprecs/fluid_prec" ).data(), "ML" );
81  list.set ( "subprecs: fluid prec", fluidPrec );
82  std::string fluidPrecDataSection = dataFile ( ( section + "/" + subsection + "/subprecs/fluid_prec_data_section" ).data(), "" );
83  list.set ( "subprecs: fluid prec data section", ( fluidPrecDataSection ).data() );
84 
85  std::string schurPrec = dataFile ( ( section + "/" + subsection + "/subprecs/schur_prec" ).data(), "ML" );
86  list.set ( "subprecs: Schur prec", schurPrec );
87  std::string schurPrecDataSection = dataFile ( ( section + "/" + subsection + "/subprecs/schur_prec_data_section" ).data(), "" );
88  list.set ( "subprecs: Schur prec data section", ( schurPrecDataSection ).data() );
89 
90  if ( displayList && verbose )
91  {
92  std::cout << "Yosida parameters list:" << std::endl;
93  std::cout << "-----------------------------" << std::endl;
94  list.print ( std::cout );
95  std::cout << "-----------------------------" << std::endl;
96  }
97 }
98 
99 Real
101 {
102  return 0.0;
103 }
104 
105 int
107 {
108  if ( M_velocityBlockSize < 0 || M_pressureBlockSize < 0 )
109  {
110  std::cout << "You must specified manually the pointers to the FESpaces" << std::endl;
111  exit ( 0 );
112  }
113 
114  const bool verbose ( M_comm->MyPID() == 0 );
115 
116  // Make sure that the preconditioner is reset
117  this->resetPreconditioner();
118 
119  std::vector<UInt> blockNumRows ( 2, 0 );
120  blockNumRows[0] = M_velocityBlockSize;
121  blockNumRows[1] = M_pressureBlockSize;
122  std::vector<UInt> blockNumColumns ( blockNumRows );
123 
124  const bool inversed ( true );
125  const bool notInversed ( false );
126  const bool notTransposed ( false );
127 
128  map_Type map ( oper->map() );
129 
130  LifeChrono timer;
131 
132  /*
133  * Getting the block structure of A
134  * / F Bt \
135  * \ B C /
136  */
137  if ( verbose )
138  {
139  std::cout << " >Getting the structure of A... ";
140  }
141  timer.start();
142  matrixBlockView_Type F, Bt, B, C, M;
143  //oper.blockView( 0, 0, F );
144  F.setup ( 0, 0, blockNumRows[0], blockNumColumns[0], oper.get() );
145 
146  //oper.blockView( 0, 1, Bt );
147  Bt.setup ( 0, blockNumColumns[0], blockNumRows[0], blockNumColumns[1], oper.get() );
148 
149  //oper.blockView( 1, 0, B );
150  B.setup ( blockNumRows[0], 0, blockNumRows[1], blockNumColumns[0], oper.get() );
151 
152  //oper.blockView( 1, 1, C );
153  C.setup ( blockNumRows[0], blockNumColumns[0], blockNumRows[1], blockNumColumns[1], oper.get() );
154 
155  if ( verbose )
156  {
157  std::cout << " done in " << timer.diff() << " s." << std::endl;
158  }
159 
160  /*
161  * Yosida:
162  * P = / F 0 \ / I F^-1Bt \
163  * \ B -S / \ 0 I /
164  * where S=dt*B*M_lumped*Bt
165  */
166 
167  // Getting the block structure of B
168  matrixBlockView_Type B11, B12, B21, B22, B22base;
169 
170  /*
171  * Building the First block
172  * / F 0 \ = / F 0 \/ I 0 \/ I 0 \
173  * \ B -S / \ 0 I /\ B I /\ 0 -S /
174  *
175  * / F 0 \
176  * \ 0 I /
177  */
178  if ( verbose )
179  {
180  std::cout << " Block 1 ( F )" << std::endl;
181  }
182  timer.start();
183  std::shared_ptr<matrixBlock_Type> P1a ( new matrixBlock_Type ( map ) );
184  P1a->setBlockStructure ( blockNumRows, blockNumColumns );
185  P1a->blockView ( 0, 0, B11 );
186  P1a->blockView ( 1, 1, B22 );
187  MatrixEpetraStructuredUtility::copyBlock ( F, B11 );
188  MatrixEpetraStructuredUtility::createIdentityBlock ( B22 );
189  P1a->globalAssemble();
190  std::shared_ptr<matrix_Type> p1a = P1a;
191  superPtr_Type precForBlock1 ( PRECFactory::instance().createObject ( M_fluidPrec ) );
192  precForBlock1->setDataFromGetPot ( M_dataFile, M_fluidDataSection );
193  // if ( M_fluidPrec == "ML2" )
194  // {
195  // PreconditionerML2* tmpPrecPtr = dynamic_cast<PreconditionerML2*> ( precForBlock1.get() );
196  // tmpPrecPtr->setFESpace ( M_uFESpace, M_pFESpace );
197  // }
198  this->pushBack ( p1a, precForBlock1, notInversed, notTransposed );
199  if ( verbose )
200  {
201  std::cout << " done in " << timer.diff() << " s." << std::endl;
202  }
203 
204  /*
205  * / I 0 \
206  * \ B I /
207  */
208  if ( verbose )
209  {
210  std::cout << " Block 1 ( B )" << std::endl;
211  }
212  timer.start();
213  std::shared_ptr<matrixBlock_Type> P1b ( new matrixBlock_Type ( map ) );
214  P1b->setBlockStructure ( blockNumRows, blockNumColumns );
215  P1b->blockView ( 0, 0, B11 );
216  P1b->blockView ( 1, 0, B21 );
217  P1b->blockView ( 1, 1, B22 );
218  MatrixEpetraStructuredUtility::copyBlock ( B, B21 );
219  ( *P1b ) *= -1;
220  MatrixEpetraStructuredUtility::createIdentityBlock ( B11 );
221  MatrixEpetraStructuredUtility::createIdentityBlock ( B22 );
222  P1b->globalAssemble();
223  std::shared_ptr<matrix_Type> p1b = P1b;
224  this->pushBack ( p1b, inversed, notTransposed );
225  if ( verbose )
226  {
227  std::cout << " done in " << timer.diff() << " s." << std::endl;
228  }
229 
230  /*
231  * / I 0 \
232  * \ 0 -S /
233  */
234  if ( verbose )
235  {
236  std::cout << " Block 1 ( Schur )" << std::endl;
237  }
238  timer.start();
239  // Computing the mass matrix
240  std::shared_ptr<matrixBlock_Type> massMat ( new matrixBlock_Type ( map ) );
241  massMat->setBlockStructure ( blockNumRows, blockNumColumns );
242  massMat->blockView ( 0, 0, M );
243  M_adrVelocityAssembler.addMass ( massMat, 1.0 / M_timestep, M.firstRowIndex(), M.firstColumnIndex() );
244  massMat->globalAssemble();
245 
246  std::shared_ptr<matrixBlock_Type> P1c ( new matrixBlock_Type ( map ) );
247 
248  std::shared_ptr<matrixBlock_Type> BBlockMat ( new matrixBlock_Type ( map ) );
249  BBlockMat->setBlockStructure ( blockNumRows, blockNumColumns );
250  BBlockMat->blockView ( 1, 0, B21 );
251  MatrixEpetraStructuredUtility::copyBlock ( B, B21 );
252  BBlockMat->globalAssemble();
253  std::shared_ptr<matrixBlock_Type> invLumpedMassBlockMat ( new matrixBlock_Type ( map ) );
254  invLumpedMassBlockMat->setBlockStructure ( blockNumRows, blockNumColumns );
255  invLumpedMassBlockMat->blockView ( 0, 0, B11 );
256  MatrixEpetraStructuredUtility::createInvDiagBlock ( M, B11 );
257  massMat.reset(); // Free memory
258  *invLumpedMassBlockMat *= -1.0;
259  invLumpedMassBlockMat->globalAssemble();
260  std::shared_ptr<matrixBlock_Type> tmpResultMat ( new matrixBlock_Type ( map ) );
261  BBlockMat->multiply ( false,
262  *invLumpedMassBlockMat, false,
263  *tmpResultMat, true );
264  BBlockMat.reset(); // Free memory
265  invLumpedMassBlockMat.reset(); // Free memory
266  std::shared_ptr<matrixBlock_Type> BtBlockMat ( new matrixBlock_Type ( map ) );
267  BtBlockMat->setBlockStructure ( blockNumRows, blockNumColumns );
268  BtBlockMat->blockView ( 0, 1, B12 );
269  MatrixEpetraStructuredUtility::copyBlock ( Bt, B12 );
270  BtBlockMat->globalAssemble();
271  tmpResultMat->multiply ( false,
272  *BtBlockMat, false,
273  *P1c, false );
274  BtBlockMat.reset();
275  tmpResultMat.reset();
276 
277  P1c->setBlockStructure ( blockNumRows, blockNumColumns );
278  P1c->blockView ( 0, 0, B11 );
279  MatrixEpetraStructuredUtility::createIdentityBlock ( B11 );
280  P1c->globalAssemble();
281  std::shared_ptr<matrix_Type> p1c = P1c;
282  superPtr_Type precForBlock2 ( PRECFactory::instance().createObject ( M_schurPrec ) );
283  precForBlock2->setDataFromGetPot ( M_dataFile, M_schurDataSection );
284  this->pushBack ( p1c, precForBlock2, notInversed, notTransposed );
285  if ( verbose )
286  {
287  std::cout << " done in " << timer.diff() << " s." << std::endl;
288  }
289 
290  /*
291  * Building the Second block
292  * / I F^-1Bt \ = / F^-1 0 \/ I Bt \/ F 0 \
293  * \ 0 I / \ 0 I /\ 0 I /\ 0 I /
294  */
295  if ( verbose )
296  {
297  std::cout << " Block 2 ( F^-1, I )" << std::endl;
298  }
299  timer.start();
300  std::shared_ptr<matrixBlock_Type> P2a ( new matrixBlock_Type ( map ) );
301  *P2a *= 0.0;
302  P2a->setBlockStructure ( blockNumRows, blockNumColumns );
303  P2a->blockView ( 0, 0, B11 );
304  P2a->blockView ( 1, 1, B22 );
305  MatrixEpetraStructuredUtility::copyBlock ( F, B11 );
306  MatrixEpetraStructuredUtility::createIdentityBlock ( B22 );
307  P2a->globalAssemble();
308  std::shared_ptr<matrix_Type> p2a = P2a;
309  this->pushBack ( p2a, inversed, notTransposed );
310  if ( verbose )
311  {
312  std::cout << " done in " << timer.diff() << " s." << std::endl;
313  }
314 
315  /*
316  * / I Bt \
317  * \ 0 I /
318  */
319  if ( verbose )
320  {
321  std::cout << " Block 2 ( Bt )" << std::endl;
322  }
323  timer.start();
324  std::shared_ptr<matrixBlock_Type> P2b ( new matrixBlock_Type ( map ) );
325  P2b->setBlockStructure ( blockNumRows, blockNumColumns );
326  P2b->blockView ( 0, 0, B11 );
327  P2b->blockView ( 0, 1, B12 );
328  P2b->blockView ( 1, 1, B22 );
329  MatrixEpetraStructuredUtility::copyBlock ( Bt, B12 );
330  ( *P2b ) *= -1; // We inverse already the block
331  MatrixEpetraStructuredUtility::createIdentityBlock ( B11 );
332  MatrixEpetraStructuredUtility::createIdentityBlock ( B22 );
333  P2b->globalAssemble();
334  std::shared_ptr<matrix_Type> p2b = P2b;
335  this->pushBack ( p2b, inversed, notTransposed );
336  if ( verbose )
337  {
338  std::cout << " done in " << timer.diff() << " s." << std::endl;
339  }
340 
341  /*
342  * / F 0 \
343  * \ 0 I /
344  */
345  if ( verbose )
346  {
347  std::cout << " Block2 ( F )" << std::endl;
348  }
349  timer.start();
350  // Here we recycle the first block that we have built (it is the same)
351  this->pushBack ( p1a, precForBlock1, notInversed, notTransposed );
352  if ( verbose )
353  {
354  std::cout << " done in " << timer.diff() << " s." << std::endl;
355  }
356 
357  this->M_preconditionerCreated = true;
358 
359  if ( verbose ) std::cout << " >All the blocks are built" << std::endl
360  << " >";
361  return ( EXIT_SUCCESS );
362 }
363 
364 int
366 {
367  return 2;
368 }
369 
370 int
372 {
373  return 2;
374 }
375 
376 void
378  const std::string& section )
379 {
380  M_dataFile = dataFile;
381  this->createParametersList ( M_list, dataFile, section, "Yosida" );
382  this->setParameters ( M_list );
383 }
384 
385 void
386 PreconditionerYosida::setParameters ( Teuchos::ParameterList& list )
387 {
388  M_precType = list.get ( "prectype", "Yosida" );
389 
390  M_fluidPrec = list.get ( "subprecs: fluid prec", "ML" );
391  M_fluidDataSection = list.get ( "subprecs: fluid prec data section", "" );
392 
393  M_schurPrec = list.get ( "subprecs: Schur prec", "ML" );
394  M_schurDataSection = list.get ( "subprecs: Schur prec data section", "" );
395 }
396 
397 void
399 {
400  // We setup the size of the blocks
401  M_velocityBlockSize = uFESpace->fieldDim() * uFESpace->dof().numTotalDof();
402  M_pressureBlockSize = pFESpace->dof().numTotalDof();
403 
404  M_uFESpace = uFESpace;
405  M_pFESpace = pFESpace;
406  M_adrVelocityAssembler.setup ( uFESpace, uFESpace ); // u,beta=u
407 }
408 
409 void
411 {
412  M_timestep = timestep;
413 }
414 
415 } // namespace LifeV
void start()
Start the timer.
Definition: LifeChrono.hpp:93
std::shared_ptr< matrix_Type > matrixPtr_Type
virtual ~PreconditionerYosida()
constructor from matrix A.
std::shared_ptr< FESpace< mesh_Type, map_Type > > FESpacePtr_Type
void createParametersList(list_Type &list, const GetPot &dataFile, const std::string &section, const std::string &subsection="Yosida")
Create the list of parameters of the preconditioner.
void updateInverseJacobian(const UInt &iQuadPt)
void setTimestep(const Real &timestep)
Setter for the timestep.
void setFESpace(FESpacePtr_Type uFESpace, FESpacePtr_Type pFESpace)
Setter for the FESpace.
double condest()
Return an estimation of the conditionement number of the preconditioner.
void setDataFromGetPot(const GetPot &dataFile, const std::string &section)
Setter using GetPot.
double Real
Generic real data.
Definition: LifeV.hpp:175
Teuchos::ParameterList list_Type
virtual void setParameters(Teuchos::ParameterList &list)
Method to setup the solver using Teuchos::ParameterList.
MatrixEpetraStructuredView< Real > matrixBlockView_Type
PreconditionerYosida(const std::shared_ptr< PreconditionerYosida > &)
std::shared_ptr< super_Type > superPtr_Type
int buildPreconditioner(matrixPtr_Type &A)
Build the preconditioner.