LifeV
TwoLevelOperator.cpp
Go to the documentation of this file.
1 /*
2  * TwoLevelOperator.cpp
3  *
4  * Created on: Oct 9, 2011
5  * Author: uvilla
6  */
7 
9 
10 namespace LifeV
11 {
12 
13 namespace Operators
14 {
15 
18 { }
19 
21 { }
22 
24 {
25  ASSERT_PRE(fineLevelOper.get() != 0, "TwoLevelOperator::SetFineLevelOperator Invalid Pointer");
26  M_fineLevelOper = fineLevelOper;
27 }
28 
30 {
31  ASSERT_PRE(smootherOper.get() != 0, "TwoLevelOperator::SetFineLevelOperator Invalid Pointer");
32  M_smootherOper = smootherOper;
33 }
34 
35 
37 {
38  ASSERT_PRE(coarseLevelOper.get() != 0, "TwoLevelOperator::SetCoarseLevelOperator Invalid Pointer");
39  M_coarseLevelOper = coarseLevelOper;
40 }
41 
43 {
44  ASSERT_PRE(restrictionOper.get() !=0, "TwoLevelOperator::SetRestrictionOperator Invalid Pointer");
45  M_restrictionOper = restrictionOper;
46 }
47 
49 {
50  ASSERT_PRE(estensionOper.get() !=0, "TwoLevelOperator::SetEstensionOperator Invalid Pointer");
51  M_estensionOper = estensionOper;
52 }
53 
55 {
56  int returnValue(0);
57  bool verbose( 0 == M_fineLevelOper->Comm().MyPID() );
58 
59  //Check that the Comm is the same:
60  if( &(M_fineLevelOper->Comm()) != &(M_coarseLevelOper->Comm()))/* == &(M_smootherOper->Comm())
61  == &(M_restrictionOper->Comm()) == &(M_estensionOper->Comm())) )*/
62  {
63  if(verbose)
64  std::cout<< "[TwoLevelOperator::checkConsistency] Comm must be the same for all operators! \n";
65  --returnValue;
66  }
67 
68  //Check that maps are correct
69  // inv(this) = inv(S) (I - A E inv(Ac) R) (I - A*inv(S))
70 
71  if(! M_fineLevelOper->OperatorRangeMap().SameAs(M_restrictionOper->OperatorDomainMap()))
72  {
73  if(verbose)
74  std::cout<< "[TwoLevelOperator::checkConsistency] Not compatible maps! \n";
75  --returnValue;
76  }
77 
78  if( ! M_restrictionOper->OperatorRangeMap().SameAs(M_coarseLevelOper->OperatorRangeMap()))
79  {
80  if(verbose)
81  std::cout<< "[TwoLevelOperator::checkConsistency] Not compatible maps! \n";
82  --returnValue;
83  }
84 
85  if( ! M_coarseLevelOper->OperatorDomainMap().SameAs(M_estensionOper->OperatorDomainMap()))
86  {
87  if(verbose)
88  std::cout<< "[TwoLevelOperator::checkConsistency] Not compatible maps! \n";
89  --returnValue;
90  }
91 
92  if( ! M_estensionOper->OperatorRangeMap().SameAs(M_fineLevelOper->OperatorDomainMap()))
93  {
94  if(verbose)
95  std::cout<< "[TwoLevelOperator::checkConsistency] Not compatible maps! \n";
96  --returnValue;
97  }
98 
99  return returnValue;
100 
101 }
102 
103 int TwoLevelOperator::SetUseTranspose(bool /*UseTranspose*/)
104 {
105  return -1.0;
106 }
107 //@}
108 
109 //! @name Mathematical functions
110 //@{
112 {
113  return M_fineLevelOper->Apply(X,Y);
114 }
115 
116 // inv(this) = inv(S) (I - A E inv(Ac) R) (I - A*inv(S))
118 {
119 
120  ASSERT_PRE(X.NumVectors() == Y.NumVectors(),
121  "[TwoLevelOperator::ApplyInverse] X and Y should have the same number of vectors.");
122  ASSERT_PRE(X.Map().SameAs(M_smootherOper->OperatorRangeMap()),
123  "[TwoLevelOperator::ApplyInverse] The map of X is not compatible with this operator.");
124  ASSERT_PRE(Y.Map().SameAs(M_smootherOper->OperatorDomainMap()),
125  "[TwoLevelOperator::ApplyInverse] The map of X is not compatible with this operator.");
126 
127  UInt nVectors(X.NumVectors());
128 
129  vector_Type Z(Y.Map(), nVectors), Rfine(Y.Map(), nVectors), Yfine(Y.Map(), nVectors);
130  vector_Type Rcoarse(M_coarseLevelOper->OperatorDomainMap(), nVectors);
131  vector_Type Ycoarse(M_coarseLevelOper->OperatorDomainMap(), nVectors);
132 
133  // y_fine = inv(S)*x
134  // r_fine = x - A*y_fine
135  EPETRA_CHK_ERR(M_smootherOper->ApplyInverse(X,Yfine));
136  EPETRA_CHK_ERR(M_fineLevelOper->Apply(Yfine, Z));
137  EPETRA_CHK_ERR(Rfine.Update(1.0, X, -1.0, Z, 0.0));
138 
139  // y_coarse = inv(Ac)*(R * r_fine)
140  EPETRA_CHK_ERR(M_restrictionOper->Apply(Rfine,Rcoarse));
141  EPETRA_CHK_ERR(M_coarseLevelOper->ApplyInverse(Rcoarse, Ycoarse));
142  // y_fine += E*y_coarse
143  EPETRA_CHK_ERR(M_estensionOper->Apply(Ycoarse, Y));
144  EPETRA_CHK_ERR(Yfine.Update(1.0, Y, 1.0));
145  // r_fine -= A*(E*y_coarse)
146  EPETRA_CHK_ERR(M_fineLevelOper->Apply(Y, Z));
147  EPETRA_CHK_ERR(Rfine.Update(-1.0, Z, 1.0));
148 
149  // y = inv(S)*r_fine
150  // y = y_fine + y
151  EPETRA_CHK_ERR(M_smootherOper->ApplyInverse(Rfine,Y));
152  EPETRA_CHK_ERR(Y.Update(1.0, Yfine, 1.0));
153 
154  return 0;
155 }
156 
157 double TwoLevelOperator::NormInf() const
158 {
159  return M_fineLevelOper->NormInf();
160 }
161 //@}
162 
163 const char * TwoLevelOperator::Label() const
164 {
165  return "TwoLevelOperator";
166 }
167 
169 {
170  return false;
171 }
172 
174 {
175  return M_fineLevelOper->HasNormInf();
176 }
177 
179 {
180  return M_fineLevelOper->Comm();
181 }
182 
184 {
185  return M_fineLevelOper->OperatorDomainMap();
186 }
187 
189 {
190  return M_fineLevelOper->OperatorRangeMap();
191 }
192 
193 
194 } /* end namespace Operators */
195 
196 } /* end namespace LifeV */
virtual int ApplyInverse(const vector_Type &X, vector_Type &Y) const
Returns the result of a raw_operator inverse applied to an raw_vector X in Y.
virtual const map_Type & OperatorRangeMap() const
Returns the raw_map object associated with the range of this operator.
virtual int Apply(const vector_Type &X, vector_Type &Y) const
Returns the result of a raw_operator applied to a raw_vector X in Y.
void SetSmootherOperator(const operatorPtr_Type &smootherOper)
Set the fine level smoother (smootherOper should have a ApplyInverse method)
virtual bool UseTranspose() const
Returns the current UseTranspose setting.
virtual const char * Label() const
Returns a character string describing the operator.
void SetRestrictionOperator(const operatorPtr_Type &restrictionOper)
Set the restriction operator from the fine to coarse level.
virtual const map_Type & OperatorDomainMap() const
Returns the raw_map object associated with the domain of this operator.
Abstract class which defines the interface of a Linear Operator.
void updateInverseJacobian(const UInt &iQuadPt)
virtual double NormInf() const
Returns the infinity norm of the global matrix.
It defines a two level methods to approximately apply the inverse of a fine level operator...
#define ASSERT_PRE(X, A)
Definition: LifeAssert.hpp:96
int checkConsistency()
Check that the range and domains of all operators are compatible.
void SetFineLevelOperator(const operatorPtr_Type &fineLevelOper)
Set the fine level operator.
virtual int SetUseTranspose(bool UseTranspose)
void SetCoarseLevelOperator(const operatorPtr_Type &coarseLevelOper)
Set the coarse level solver (coarseLevelOper should have a ApplyInverse method)
virtual bool HasNormInf() const
Returns true if the this object can provide an approximate Inf-norm, false otherwise.
void SetEstensionOperator(const operatorPtr_Type &estensionOper)
Set the extension operatoe from the coarse to fine level.
virtual const comm_Type & Comm() const
Returns a pointer to the Epetra_Comm communicator associated with this operator.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
std::shared_ptr< operator_Type > operatorPtr_Type