LifeV
aSIMPLEOperator.cpp
Go to the documentation of this file.
1 #include <lifev/navier_stokes_blocks/solver/aSIMPLEOperator.hpp>
2 
3 #include <lifev/core/linear_algebra/IfpackPreconditioner.hpp>
4 #include <lifev/core/linear_algebra/MLPreconditioner.hpp>
5 #include <lifev/core/linear_algebra/TwoLevelPreconditioner.hpp>
6 #include <lifev/core/linear_algebra/AztecooOperatorAlgebra.hpp>
7 #include <lifev/core/linear_algebra/BelosOperatorAlgebra.hpp>
8 #include <lifev/core/linear_algebra/ApproximatedInvertibleRowMatrix.hpp>
9 
10 namespace LifeV
11 {
12 namespace Operators
13 {
14 //===========================================================================//
15 // Constructors
16 //===========================================================================//
17 
18 aSIMPLEOperator::aSIMPLEOperator():
19  M_label("aSIMPLEOperator"),
20  M_useTranspose(false),
21  M_approximatedMomentumOperator ( new Operators::ApproximatedInvertibleRowMatrix ),
22  M_approximatedSchurComplementOperator ( new Operators::ApproximatedInvertibleRowMatrix ),
23  M_useStabilization ( false )
24 {
25 
26 }
27 
28 aSIMPLEOperator::~aSIMPLEOperator()
29 {
30 
31 }
32 
33 // show information about the class
34 void aSIMPLEOperator::showMe(){
35  //std::cout<<"Dimension u: "<< M_Bt->NumGlobalRows()<<
36  //", Dimension p: "<<M_Bt->NumGlobalCols()<<std::endl;
37  //std::cout<<"Pressure correction order "<<M_p<<std::endl;
38 }
39 
40 void aSIMPLEOperator::setUp(const matrixEpetraPtr_Type & F,
41  const matrixEpetraPtr_Type & B,
42  const matrixEpetraPtr_Type & Btranspose)
43 {
44  M_F = F;
45  M_B = B;
46  M_Btranspose = Btranspose;
47  M_comm = F->map().commPtr();
48  M_monolithicMap.reset( new mapEpetra_Type ( M_F->map() ) );
49  *M_monolithicMap += M_B->map();
50  M_Z.reset(new VectorEpetra_Type( F->map(), Unique ) );
51  M_X_velocity.reset( new VectorEpetra_Type (M_F->map(), Unique) );
52  M_X_pressure.reset( new VectorEpetra_Type (M_B->map(), Unique) );
53  M_Y_velocity.reset( new VectorEpetra_Type (M_F->map(), Unique ) );
54  M_Y_pressure.reset( new VectorEpetra_Type (M_B->map(), Unique) );
55  M_useStabilization = false;
56  M_domainDBT.reset( new mapEpetra_Type ( M_B->rangeMap() ) );
57  M_rangeDBT.reset( new mapEpetra_Type ( M_B->domainMap() ) );
58 
59 }
60 
61 void aSIMPLEOperator::setUp(const matrixEpetraPtr_Type & F,
62  const matrixEpetraPtr_Type & B,
63  const matrixEpetraPtr_Type & Btranspose,
64  const matrixEpetraPtr_Type & D)
65 {
66  M_F = F;
67  M_B = B;
68  M_Btranspose = Btranspose;
69  M_D.reset( new matrixEpetra_Type ( *D ) );
70  M_D->globalAssemble();
71  M_comm = F->map().commPtr();
72  M_monolithicMap.reset( new mapEpetra_Type ( M_F->map() ) );
73  *M_monolithicMap += M_B->map();
74  M_Z.reset(new VectorEpetra_Type( M_B->domainMap(), Unique ) );
75  M_X_velocity.reset( new VectorEpetra_Type (M_F->map(), Unique) );
76  M_X_pressure.reset( new VectorEpetra_Type (M_B->map(), Unique) );
77  M_Y_velocity.reset( new VectorEpetra_Type (M_F->map(), Unique ) );
78  M_Y_pressure.reset( new VectorEpetra_Type (M_B->map(), Unique) );
79  M_useStabilization = true;
80  M_domainDBT.reset( new mapEpetra_Type ( M_B->rangeMap() ) );
81  M_rangeDBT.reset( new mapEpetra_Type ( M_B->domainMap() ) );
82 }
83 
84 
85 void aSIMPLEOperator::setOptions(const Teuchos::ParameterList& solversOptions)
86 {
87  std::shared_ptr<Teuchos::ParameterList> schurOptions;
88  schurOptions.reset(new Teuchos::ParameterList(solversOptions.sublist("ApproximatedSchurOperator")) );
89  setSchurOptions(schurOptions);
90 
91  std::shared_ptr<Teuchos::ParameterList> momentumOptions;
92  momentumOptions.reset(new Teuchos::ParameterList(solversOptions.sublist("MomentumOperator")) );
93  setMomentumOptions(momentumOptions);
94 }
95 
96 void aSIMPLEOperator::setMomentumOptions(const parameterListPtr_Type & _oList)
97 {
98  ASSERT_PRE(_oList.get() != 0, "oList pointer not valid");
99  M_momentumOptions = _oList;
100 }
101 
102 
103 void aSIMPLEOperator::setSchurOptions(const parameterListPtr_Type & _oList)
104 {
105  ASSERT_PRE(_oList.get() != 0, "oList pointer not valid");
106  M_schurOptions = _oList;
107 }
108 
109 void aSIMPLEOperator::updateApproximatedMomentumOperator( )
110 {
111  M_approximatedMomentumOperator->SetRowMatrix(M_F->matrixPtr());
112  M_approximatedMomentumOperator->SetParameterList(*M_momentumOptions);
113  M_approximatedMomentumOperator->Compute();
114 
115 }
116 
117 void aSIMPLEOperator::updateApproximatedSchurComplementOperator( )
118 {
119  buildShurComplement();
120  M_approximatedSchurComplementOperator->SetRowMatrix(M_schurComplement->matrixPtr());
121  M_approximatedSchurComplementOperator->SetParameterList(*M_schurOptions);
122  M_approximatedSchurComplementOperator->Compute();
123 }
124 
125 void aSIMPLEOperator::buildShurComplement( )
126 {
127  Epetra_Vector diag( M_F->matrixPtr()->OperatorRangeMap() );
128  M_invD.reset(new Epetra_Vector( M_F->matrixPtr()->OperatorRangeMap() ) );
129 
130  // extracting diag(F)
131  M_F->matrixPtr()->ExtractDiagonalCopy(diag);
132 
133  // computing diag(F)^{-1}
134  M_invD->Reciprocal(diag);
135 
136  // computing diag(F)^{-1}*M_Btranspose
137  matrixEpetra_Type FBT (*M_Btranspose);
138  FBT.matrixPtr()->LeftScale(*M_invD);
139 
140  M_schurComplement.reset ( new matrixEpetra_Type ( M_B->map() ) );
141 
142  // computing M_B*(diag(F)^{-1}*M_Btranspose)
143  M_B->multiply (false, FBT, false, *M_schurComplement, false);
144  if ( M_useStabilization )
145  {
146  *M_D *= -1.0;
147  *M_schurComplement += *M_D;
148  }
149 
150  M_schurComplement->globalAssemble();
151 
152  M_DBT.reset ( new matrixEpetra_Type( *M_Btranspose ) );
153  M_DBT->matrixPtr()->LeftScale(*M_invD);
154  M_DBT->globalAssemble( M_domainDBT, M_rangeDBT );
155 }
156 
157 inline int aSIMPLEOperator::ApplyInverse( VectorEpetra_Type const& X_velocity,
158  VectorEpetra_Type const& X_pressure,
159  VectorEpetra_Type & Y_velocity,
160  VectorEpetra_Type & Y_pressure) const
161 {
162  M_approximatedMomentumOperator->ApplyInverse(X_velocity.epetraVector(), M_Z->epetraVector() );
163 
164  M_approximatedSchurComplementOperator->ApplyInverse( (*M_B*(*M_Z) - X_pressure ).epetraVector(), Y_pressure.epetraVector());
165 
166  Y_velocity = (*M_Z - *M_DBT*Y_pressure);
167 
168  return 0;
169 
170 }
171 
172 
173 int aSIMPLEOperator::ApplyInverse(const vector_Type& X, vector_Type& Y) const
174 {
175  ASSERT_PRE(X.NumVectors() == Y.NumVectors(), "X and Y must have the same number of vectors");
176 
177  const VectorEpetra_Type X_vectorEpetra(X, M_monolithicMap, Unique);
178 
179  // gather input values
180  M_X_velocity->subset(X_vectorEpetra, M_F->map(), 0, 0);
181  M_X_pressure->subset(X_vectorEpetra, M_B->map(), M_F->map().mapSize(), 0);
182 
183  ApplyInverse( *M_X_velocity, *M_X_pressure, *M_Y_velocity, *M_Y_pressure);
184 
185  // output vector
186  VectorEpetra_Type Y_vectorEpetra(M_monolithicMap, Unique);
187 
188  // Copy the individual parts inside
189  Y_vectorEpetra.subset(*M_Y_velocity, M_X_velocity->map(), 0, 0);
190  Y_vectorEpetra.subset(*M_Y_pressure, M_X_pressure->map(), 0, M_X_velocity->map().mapSize() );
191 
192  Y = dynamic_cast<Epetra_MultiVector&>( Y_vectorEpetra.epetraVector() );
193 
194  return 0;
195 }
196 
197 } /* end namespace Operators */
198 
199 } /*end namespace */
VectorEpetra(const MapEpetra &map, const MapEpetraType &mapType=Unique, const combineMode_Type combineMode=Add)
Constructor - Using Maps.
void updateInverseJacobian(const UInt &iQuadPt)
#define ASSERT_PRE(X, A)
Definition: LifeAssert.hpp:96
vector_type & epetraVector()
Return the VectorEpetra in the wrapper.