LifeV
PreconditionerTeko.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 PreconditionerTeko
30 
31  @author Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
32  @maintainer Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
33 
34  @date 14-10-2010
35  */
36 
38 
39 #ifdef LIFEV_HAVE_TEKO
40 
41 namespace LifeV
42 {
43 
44 PreconditionerTeko::PreconditionerTeko ( const std::shared_ptr<Epetra_Comm>& comm ) :
45  PreconditionerBlock ( comm ), M_prec()
46 {
47 
48 }
49 
50 PreconditionerTeko::PreconditionerTeko ( PreconditionerTeko& P, const std::shared_ptr<Epetra_Comm>& comm ) :
51  PreconditionerBlock ( P, comm )
52 {
53 
54 }
55 
56 PreconditionerTeko::~PreconditionerTeko()
57 {
58 
59 }
60 
61 PreconditionerTeko::operatorPtr_Type
62 PreconditionerTeko::preconditionerPtr()
63 {
64  return M_prec;
65 }
66 
67 PreconditionerTeko::operator_Type*
68 PreconditionerTeko::preconditioner()
69 {
70  return M_prec.get();
71 }
72 
73 void
74 PreconditionerTeko::resetPreconditioner()
75 {
76  M_oper.reset();
77  M_prec.reset();
78 
79  this->M_preconditionerCreated = false;
80 }
81 
82 bool
83 PreconditionerTeko::isPreconditionerSet() const
84 {
85  return M_prec != 0 ? true : false;
86 }
87 
88 int
89 PreconditionerTeko::SetUseTranspose ( const bool useTranspose )
90 {
91  return M_prec->SetUseTranspose ( useTranspose );
92 }
93 
94 bool
95 PreconditionerTeko::UseTranspose()
96 {
97  return M_prec->UseTranspose();
98 }
99 int
100 PreconditionerTeko::ApplyInverse ( const Epetra_MultiVector& X, Epetra_MultiVector& Y ) const
101 {
102  return M_prec->ApplyInverse ( X, Y );
103 }
104 
105 int
106 PreconditionerTeko::Apply ( const Epetra_MultiVector& X, Epetra_MultiVector& Y ) const
107 {
108  return M_prec->Apply ( X, Y );
109 }
110 
111 const Epetra_Map&
112 PreconditionerTeko::OperatorRangeMap() const
113 {
114  return M_prec->OperatorRangeMap();
115 }
116 
117 const Epetra_Map&
118 PreconditionerTeko::OperatorDomainMap() const
119 {
120  return M_prec->OperatorRangeMap();
121 }
122 
123 void
124 PreconditionerTeko::buildBlockGIDs ( std::vector<std::vector<int> >& gids,
125  const MapEpetra& map,
126  const std::vector<int>& blockSizes )
127 {
128  int numLocal = map.map ( Unique )->NumMyElements();
129  int numBlocks = blockSizes.size();
130 
131  gids.clear();
132  gids.resize ( blockSizes.size() );
133 
134  int gid = -1;
135  int cumulBlocksSizes = 0;
136 
137  for ( int i ( 0 ); i < numLocal; ++i )
138  {
139  gid = map.map ( Unique )->GID ( i );
140  cumulBlocksSizes = 0;
141  for ( int j ( 0 ); j < numBlocks; ++j )
142  {
143  cumulBlocksSizes += blockSizes[j];
144  if ( gid <= cumulBlocksSizes )
145  {
146  gids[j].push_back ( gid );
147  break;
148  }
149  }
150  }
151 }
152 
153 void
154 PreconditionerTeko::buildPreconditionerTeko ( RCP<Teko::BlockPreconditionerFactory> precFact,
155  matrixPtr_Type& oper,
156  const std::vector<int>& blockSizes )
157 {
158  // Building the preconditioner
159  Teko::Epetra::EpetraBlockPreconditioner* prec = new Teko::Epetra::EpetraBlockPreconditioner ( precFact );
160 
161  M_oper = oper->matrixPtr();
162 
163  std::vector<std::vector<int> > vec;
164  buildBlockGIDs ( vec, oper->rangeMap(), blockSizes );
165 
166  // Building the block operator from the matrix
167  Teuchos::RCP<Teko::Epetra::BlockedEpetraOperator> sA
168  = Teuchos::rcp ( new Teko::Epetra::BlockedEpetraOperator ( vec, Teuchos::rcp ( M_oper.get() ) ) );
169 
170  M_prec.reset ( prec );
171 
172  //Building explicitly the preconditioner
173  M_prec->buildPreconditioner ( sA );
174 
175  if ( !M_prec.get() )
176  {
177  //! if not filled, I do not know how to diagonalize.
178  ERROR_MSG ( "Preconditioner not set, something went wrong in its computation\n" );
179  }
180 
181  this->M_preconditionerCreated = true;
182 }
183 
184 
185 } // namespace LifeV
186 
187 #endif // LIFEV_HAVE_TEKO