LifeV
MonolithicBlock.hpp
Go to the documentation of this file.
1 /* -*- mode: c++ -*- */
2 //@HEADER
3 /*
4 *******************************************************************************
5 
6  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
7  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
8 
9  This file is part of LifeV.
10 
11  LifeV is free software; you can redistribute it and/or modify
12  it under the terms of the GNU Lesser General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  LifeV is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  Lesser General Public License for more details.
20 
21  You should have received a copy of the GNU Lesser General Public License
22  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
23 
24 *******************************************************************************
25 */
26 //@HEADER
27 
28 /*!
29  @file
30  @brief This file contains a pure virtual class for the linear operators with a block structure
31  (i.e. block matrices and preconditioners). The specializations of this class can be used to handle many
32  types of composed preconditioners and composed operators.
33 
34  @author Paolo Crosetto <crosetto@iacspc70.epfl.ch>
35  @date 07 Jun 2010
36  */
37 
38 #ifndef MONOLITHICBLOCK_H
39 #define MONOLITHICBLOCK_H 1
40 
41 #include <cstdarg>
42 
43 #include <Epetra_Comm.h>
44 #include <Epetra_Operator.h>
45 
46 #include <lifev/core/filter/GetPot.hpp>
47 #include <lifev/core/LifeV.hpp>
48 
49 #include <lifev/core/algorithm/SolverAztecOO.hpp>
50 #include <lifev/core/algorithm/PreconditionerIfpack.hpp>
51 
52 #include <lifev/core/fem/FESpace.hpp>
53 #include <lifev/core/fem/BCManage.hpp>
54 
55 #include <lifev/core/algorithm/ComposedOperator.hpp>
56 
57 #include <lifev/core/mesh/RegionMesh.hpp>
58 
59 namespace LifeV
60 {
61 
62 //! MonolithicBlock - This is a pure virtual class for the linear operators with a block structure
63 /*! (i.e. block matrices and preconditioners).
64  @author Paolo Crosetto
65 
66  The specializations of this class can be used to handle many
67  types of composed preconditioners and composed operators. It conteins a vector of pointers to EpetraMatrix
68  holding the diferent blocks. These matrices should be zero everywhere but on the diagonal block corresponding
69  to the corresponding problem. This class also handles the coupling through a vector of pointer to coupling matrices.
70  */
71 
72 class MonolithicBlock
73 {
74 public:
75 
76  //! @name Public Types
77  //@{
78  typedef VectorEpetra vector_Type;
79  typedef std::shared_ptr< vector_Type > vectorPtr_Type;
80  typedef MatrixEpetra< Real > matrix_Type;
81  typedef std::shared_ptr< matrix_Type > matrixPtr_Type;
82  typedef std::shared_ptr< Epetra_Operator > epetraOperatorPtr_Type;
83  typedef std::shared_ptr< Preconditioner > epetra_preconditioner_ptrtype;
84  typedef matrix_Type::matrix_type/*matrix_Type*/ epetraMatrix_Type;
85  typedef SolverAztecOO solver_Type;
86  typedef std::shared_ptr< SolverAztecOO > solverPtr_Type;
87  typedef FESpace<RegionMesh<LinearTetra>, MapEpetra> fespace_Type;
88  typedef std::shared_ptr< fespace_Type > fespacePtr_Type;
89  typedef std::shared_ptr< MapEpetra > mapPtr_Type;
90  typedef std::shared_ptr< BCHandler > bchandlerPtr_Type;
91  //@}
92 
93 
94  //! @name Constructor & Destructor
95  //@{
96  //! Empty Constructor
97  MonolithicBlock() :
98  M_bch(),
99  M_blocks(),
100  M_FESpace(),
101  M_offset(),
102  M_numerationInterface(),
103  M_comm()
104  {}
105 
106  // MonolithicBlock( Int flag ):
107  // M_bch(),
108  // M_blocks(),
109  // M_FESpace(),
110  // M_comm(),
111  // M_superCouplingFlag(flag)
112  // {}
113 
114  //! Destructor
115  virtual ~MonolithicBlock()
116  {
117  }
118  //@}
119 
120 
121 
122  //! @name Pure virtual methods
123  //@{
124  //! Solves the preconditioned linear system (used only when dealing with a preconditioner)
125  /*!
126  Provided the linear solver and the right hand side this method computes the solution and returns it into
127  the result vector.
128  @param rhs right hand side of the linear system
129  @param result output result
130  @param linearSolver the linear system
131  */
132  virtual int solveSystem ( const vector_Type& rhs, vector_Type& result, solverPtr_Type& linearSolver) = 0;
133 
134  //! Sets the parameters needed by the preconditioner from data file
135  /*!
136  @param data GetPot object reading the text data file
137  @param section string specifying the path in the data file where to find the options for the operator
138  */
139  virtual void setDataFromGetPot (const GetPot& data, const std::string& section) = 0;
140 
141 
142  //! Sets the parameters needed by the preconditioner from data file
143  /*!
144  @param data GetPot object reading the text data file
145  @param section string specifying the path in the data file where to find the options for the operator
146  */
147  virtual void setupSolver (solver_Type& /*solver*/, const GetPot& /*data*/) {}
148 
149  //! pushes a block at the end of the vector
150  /*!
151  adds a new block
152  @param Mat block matrix to push
153  @param recompute flag stating wether the preconditioner for this block have to be recomputed at every time step
154  */
155  virtual void push_back_matrix ( const matrixPtr_Type& Mat, const bool recompute ) = 0;
156 
157  //!
158  /*!
159  adds a new block
160  @param Mat block matrix to push
161  @param recompute flag stating wether the preconditioner for this block have to be recomputed at every time step
162  */
163  virtual void addToCoupling ( const matrixPtr_Type& Mat, UInt position ) = 0;
164 
165  //!
166  /*!
167  adds an entry to the coupling matrix
168  @param entry entry
169  @param row row for the insertion
170  @param col colon for the insertion
171  */
172  virtual void addToCoupling ( const Real& entry , UInt row, UInt col, UInt position ) = 0;
173 
174  //! If not present in the derived class it must not be called (gives an assertion fail)
175  virtual void setRecompute (UInt /*position*/, bool /*flag*/)
176  {
177  assert (false);
178  }
179 
180  //! replaces a block
181  /*!
182  replaces a block on a specified position in the vector
183  @param Mat block matrix to push
184  @param index position in the vector
185  */
186  virtual void replace_matrix ( const matrixPtr_Type& Mat, UInt index) = 0;
187 
188 
189  //! replaces a coupling block
190  /*!
191  replaces a block on a specified position in the vector
192  @param Mat block matrix to push
193  @param index position in the vector
194  */
195  virtual void replace_coupling ( const matrixPtr_Type& Mat, UInt index) = 0;
196 
197  //! runs GlobalAssemble on the blocks
198  /*!
199  closes and distributes all the matrices before computing the preconditioner
200  */
201  virtual void GlobalAssemble() = 0;
202 
203 
204  //!sums the coupling matrices with the corresponding blocks
205  /*!
206  Everything (but the boundary conditions) must have been set before calling this
207  */
208  virtual void blockAssembling() {}
209 
210  //! Computes the coupling
211  /*!
212  computes all the coupling blocks specific for the chosen preconditioner. The coupling is handled
213  through an augmented formulation, introducing new variables (multipliers). Needs as input: the global map of the problem,
214  the FESpaces of the subproblems to be coupled with their offsets, a std::map holding the two numerations of the
215  interface between the two subproblems (the numeration can be different but the nodes must be matching in each
216  subdomain), an EpetraVector defined on the multipliers map containing the corresponding dof at the interface (NB: the multipliers map should be constructed from the second numeration in the std::map).
217  Note that the FESpaces and the offsets have to be set before calling this method.
218  @param map the map of the global problem
219  @param locDofMap std::map with the correspondence between the interface dofs for the two different maps in
220  the subproblems
221  @param numerationInterface vector containing the correspondence of the Lagrange multipliers with the interface dofs
222  */
223  virtual void coupler (mapPtr_Type& map,
224  const std::map<ID, ID>& locDofMap,
225  const vectorPtr_Type& numerationInterface,
226  const Real& timeStep,
227  const Real& coefficient,
228  const Real& rescaleFactor) = 0;
229 
230 
231 
232  //! Adds a default coupling block at a specified position
233  /*!
234  The coupling is handled
235  through an augmented formulation, introducing new variables (multipliers). Needs as input: the global map of the problem,
236  the two FESpaces of the subproblems to be coupled with their offsets, a std::map holding the two numerations of the
237  interface between the two subproblems (the numeration can be different but the nodes must be matching in each
238  subdomain), an EpetraVector defined on the multipliers map containing the corresponding dof at the interface (NB: the multipliers map should be constructed from the second numeration in the std::map)
239  @param map the map of the global problem
240  @param FESpace1 FESpace of the first problem
241  @param offset1 offset for the first block in the global matrix
242  @param FESpace2 FESpace of the second problem
243  @param offset2 offset for the second block in the global matrix
244  @param locDofMap std::map with the correspondence between the interface dofs for the two different maps in
245  the subproblems
246  @param numerationInterface vector containing the correspondence of the Lagrange multipliers with the interface dofs
247  @param couplingBlock: flag specifying the block associated with the coupling. See MonolithicBlock::couplingMatrix to understand what the values
248  for this flag correspond to.
249  @param couplingFlag: flag specifying which block must be coupled whith which block.
250  */
251  virtual void coupler (mapPtr_Type& map,
252  const std::map<ID, ID>& locDofMap,
253  const vectorPtr_Type& numerationInterface,
254  const Real& timeStep,
255  const Real& coefficient,
256  const Real& rescaleFactor,
257  UInt couplingFlag
258  ) = 0;
259 
260  //! returns true if the operator is set
261  /*!
262  */
263  virtual bool set() = 0;
264 
265  //! Pushes a new coupling matrix in the corresponding vector
266  virtual void push_back_coupling ( matrixPtr_Type& coupling) = 0;
267  //@}
268 
269  //@name virtual methods
270  //@{
271  //!replace a block preconditioner
272  /*!
273  (only used if the operator is a preconditioner)
274  */
275  virtual void replace_precs ( const epetraOperatorPtr_Type& /*Mat*/, UInt /*index*/)
276  {
277  ERROR_MSG ("this method should not be implemented");
278  }
279 
280  //!pushes back a block preconditioner
281  /*!
282  (only used if the operator is a preconditioner)
283  */
284  virtual void push_back_precs (const epetraOperatorPtr_Type& /*Mat*/)
285  {
286  ERROR_MSG ("this method should not be implemented");
287  }
288  //@}
289 
290  //!replaces a BCHandler
291  /*!
292  replaces a BCHandler in the vector of bcHandlers at a specified position
293  \param bch: input BCHandler to replace
294  \param position: position
295  */
296  virtual void replace_bch (bchandlerPtr_Type& /*bch*/, UInt /*position*/) {};
297 
298  //!Applies the correspondent boundary conditions to every block
299  /*!
300  note that this method must be called after blockAssembling(), that sums the coupling conditions to the blocks
301  \param time: time
302  */
303  virtual void applyBoundaryConditions (const Real& time);
304 
305  //!Applies the correspondent boundary conditions to a specified block
306  /*!
307  note that this method must be called after blockAssembling(), that sums the coupling conditions to the blocks
308  \param time: time
309  \param block: number of the block
310  */
311  virtual void applyBoundaryConditions (const Real& time, const UInt block);
312 
313 
314  //!resets the blocks (frees the shared pointers)
315  /*!
316  */
317  virtual void resetBlocks()
318  {
319  M_blocks.clear();
320  }
321 
322  //!sets the communicator
323  /*!
324  */
325  virtual void setComm (std::shared_ptr<Epetra_Comm> comm )
326  {
327  M_comm = comm;
328  }
329 
330  //!resets the blocks, boundary conditions, FE spaces.
331  /*!
332  */
333  virtual void reset()
334  {
335  M_blocks.clear();
336  M_bch.clear();
337  M_FESpace.clear();
338  M_offset.clear();
339  }
340 
341  //!Applies the robin preconditioners
342  /*!
343  Applies the robin preconditioners when needed, otherwise does nothing
344  */
345  virtual void setRobin (matrixPtr_Type& /*mat*/, vectorPtr_Type& /*rhs*/) {}
346 
347 
348  //! builds the coupling matrix.
349  /*!
350  Computes the matrix that couples 2 (or more) blocks using an augmented formulation (Lagrange multipliers).
351  It adds from 1 to 4 coupling blocks, depending on the flag 'coupling'. This flag is an Int, it works as
352  the bash command chmod. It ranges from 1 to 15 for two blocks. The values from 15 to 31 account for the presence
353  of a third block: in FSI these three blocks are the fluid block, the structure and the fluid mesh displacement
354  blocks. For 'coupling > 31' the method is called recursively.
355  \param bigMatrix: the coupling matrix to be built
356  \param coupling: flag specifying what wether to consider all the coupling or to neglect one part
357  \param problem1: FESpace of the first block
358  \param offset1: offset of the first block
359  \param problem2: FESpace of the second block
360  \param offset2: offset of the second block
361  \param locDofMap: std::map with the correspondence between the interface dofs for the two different maps in
362  the subproblems
363  \param numerationInterface vector containing the correspondence of the Lagrange multipliers with the interface dofs
364  \param value value to insert in the coupling blocks
365  */
366  void couplingMatrix (matrixPtr_Type& bigMatrix,
367  Int flag,
368  const std::vector<fespacePtr_Type>& problem,
369  const std::vector<UInt>& offset,
370  const std::map<ID, ID>& locDofMap,
371  const vectorPtr_Type& numerationInterface,
372  const Real& timeStep = 1.e-3,
373  const Real& value = 1.,
374  const Real& coefficient = 1.,
375  const Real& rescaleFactor = 1.); // not working with non-matching grids
376 
377 
378  //!sets the vector of raw pointer to the BCHandler
379  /*!
380  each entry of the vector correspond to a block in the same
381  position in the vector of matrix pointers M_blocks. A vector of any size can be passed.
382  \param vec: the vector of BCHandlers
383  */
384  void setConditions (std::vector<bchandlerPtr_Type>& vec );
385 
386 
387  //!sets the vector of raw pointer to the FESpaces
388  /*!
389  A vector of arbitrary size can be passed
390  \param vec: the vector of FESpaces
391  */
392  void setSpaces ( std::vector<fespacePtr_Type>& vec );
393 
394  //!sets the vector of raw pointer to the offsets of the different blocks
395  /*!
396  An arbitrary number of raw pointers can be passed.
397  \param blocks: total number of input offsets
398  */
399  void setOffsets ( UInt blocks, .../*fespacePtr_Type ptr1, fespacePtr_Type ptr2*/);
400 
401 
402  //!computes the Robin coupling matrix
403  /*!
404  Computes a matrix that mixes the coupling conditions between the blocks:
405  [0,0,0,0;0,0,0,alphaf;0,0,0,0;0,alphas,0,0].
406 
407  If the coupling
408  conditions are of Dirichlet and Neumann type (e.g. continuity of velocity and stress) then the preconditioned
409  system will have two Robin conditions instead.
410  \param matrix: the input matrix that will hold the robin coupling;
411  \param alphaf: parameter multiplying the b.c. of the first block;
412  \param alphas: parameter multiplying the b.c. of the second block;
413  \param coupling: flag specifying if we want to neglect part of the coupling (used for preconditioning purposes);
414  \param map: global map of the whole problem;
415  \param FESpace1: FESpace of the first block;
416  \param offset1: offset of the first block in the global matrix;
417  \param FESpace2: FESpace of the second block;
418  \param offset2: offset of the second block in the global matrix;
419  \param locDofMap: std::map with the correspondance between the numeration of the interface in the 2 FE spaces.
420  \param numerationInterface: vector containing the correspondence of the Lagrange multipliers with the interface dofs
421  */
422  void robinCoupling ( MonolithicBlock::matrixPtr_Type& matrix,
423  Real& alphaf,
424  Real& alphas,
425  UInt coupling,
426  const MonolithicBlock::fespacePtr_Type& FESpace1,
427  const UInt& offset1,
428  const MonolithicBlock::fespacePtr_Type& FESpace2,
429  const UInt& offset2,
430  const std::map<ID, ID>& locDofMap,
431  const MonolithicBlock::vectorPtr_Type& numerationInterface );
432 
433 
434  //!
435  /*!
436  adds a new block
437  @param Mat block matrix to push
438  @param position position of the matrix to which we want to add Mat
439  */
440  virtual void addToBlock ( const matrixPtr_Type& Mat, UInt position );
441 
442  //! Pushes a new block
443  /** Pushes a matrix, BCHandler, FESpace and offset in the correspondent vector*/
444  virtual void push_back_oper ( MonolithicBlock& Oper);
445 
446  //@}
447 
448  //!@name Get Methods
449  //@{
450  //! returns the vector of pointers to the blocks (by const reference).
451  const std::vector<matrixPtr_Type>& blockVector()
452  {
453  return M_blocks;
454  }
455 
456  //! returns the vector of pointers to the BCHandlers (by const reference).
457  const std::vector<bchandlerPtr_Type>& BChVector()
458  {
459  return M_bch;
460  }
461 
462  //! returns the vector of pointers to the FE spaces (by const reference).
463  const std::vector<fespacePtr_Type>& FESpaceVector()
464  {
465  return M_FESpace;
466  }
467 
468  //! returns the vector of the offsets (by const reference).
469  const std::vector<UInt>& offsetVector()
470  {
471  return M_offset;
472  }
473 
474  virtual const UInt whereIsBlock ( UInt position ) const = 0;
475 
476  //@}
477 
478 protected:
479 
480  //! @name Protected Methods
481  //@{
482 
483  //!sums the coupling matrix in the specified position with the corresponding block
484  /*!
485  Everything (but the boundary conditions) must have been set before calling this
486  */
487  virtual void blockAssembling (const UInt /*k*/) {}
488 
489  //!swaps two std::shared_ptr. The tamplate argument of the shared_ptr is templated
490  /*!
491  \param operFrom shared_ptr to be swapped
492  \param operTo shared_ptr to be swapped
493  */
494  template <typename Operator>
495  void
496  swap (std::shared_ptr<Operator>& operFrom, std::shared_ptr<Operator>& OperTo);
497 
498  //!swaps two std::shared_ptr. The tamplate argument of the shared_ptr is templated
499  /*!
500  \param operFrom shared_ptr to be swapped
501  \param operTo shared_ptr to be swapped
502  */
503  template <typename Operator>
504  void
505  insert (std::vector<Operator>& operFrom, std::vector<Operator>& OperTo);
506  //@}
507 
508  //! @name Protected Members
509  //@{
510  //ComposedOperator<Epetra_Operator> M_blocks;
511  std::vector<bchandlerPtr_Type> M_bch;
512  std::vector<matrixPtr_Type> M_blocks;
513  std::vector<fespacePtr_Type> M_FESpace;
514  std::vector<UInt> M_offset;
515  vectorPtr_Type M_numerationInterface;
516  std::shared_ptr<Epetra_Comm> M_comm;
517  //Int M_superCouplingFlag;
518  //@}
519  //std::shared_ptr<OperatorPtr> M_blockPrec;
520 private:
521 
522  //! @name Private Methods
523  //@{
524 
525  //!private copy constructor: this class should not be copied.
526  /*!
527  If you need a copy you should implement it, so that it copies the shared pointer one by one, without copying
528  the content.
529  */
530  MonolithicBlock ( const MonolithicBlock& /*T*/) {}
531  //@}
532 };
533 
534 
535 typedef FactorySingleton<Factory<MonolithicBlock, std::string> > BlockPrecFactory;
536 
537 template <typename Operator>
538 void
539 MonolithicBlock::swap (std::shared_ptr<Operator>& operFrom, std::shared_ptr<Operator>& operTo)
540 {
542  operFrom = operTo;
543  operTo = tmp;
544 }
545 
546 
547 template <typename Operator>
548 void
549 MonolithicBlock::insert (std::vector<Operator>& vectorFrom, std::vector<Operator>& vectorTo)
550 {
552 }
553 
554 
555 } // Namespace LifeV
556 
557 #endif /* MONOLITHICBLOCK_H */
void assignFunction(bcBase_Type &base)
Assign the function to the base of the BCHandler.
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
double Real
Generic real data.
Definition: LifeV.hpp:175
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191