Memosa-FVM  0.2
BCGStab.cpp
Go to the documentation of this file.
1 // This file os part of FVM
2 // Copyright (c) 2012 FVM Authors
3 // See LICENSE file for terms.
4 
5 #ifdef FVM_PARALLEL
6 #include <mpi.h>
7 #endif
8 
9 
10 #include "BCGStab.h"
12  preconditioner(0),
13  _totalIterations(0)
14 {}
15 
17 {
18 }
19 
20 void
22 {
24 }
25 
26 MFRPtr
28 {
29  const MultiFieldMatrix& matrix = ls.getMatrix();
30 
31  // original system is in delta form
32  shared_ptr<MultiField> x(ls.getDeltaPtr());
33  shared_ptr<MultiField> bOrig(ls.getBPtr());
34 
35  matrix.computeResidual(ls.getDelta(),ls.getB(),ls.getResidual());
36 
37  MFRPtr rNorm0(ls.getResidual().getOneNorm());
38 
39  shared_ptr<MultiField> r(dynamic_pointer_cast<MultiField>(ls.getResidual().newCopy()));
40  shared_ptr<MultiField> rTilda(dynamic_pointer_cast<MultiField>(ls.getResidual().newCopy()));
41 
42  shared_ptr<MultiField> p;
43  shared_ptr<MultiField> pHat(dynamic_pointer_cast<MultiField>(x->newClone()));
44  shared_ptr<MultiField> v(dynamic_pointer_cast<MultiField>(x->newClone()));
45  shared_ptr<MultiField> t(dynamic_pointer_cast<MultiField>(x->newClone()));
46 
47  MFRPtr rho;
48  MFRPtr rhoPrev;
49 
50  MFRPtr alpha;
51  MFRPtr omega;
52 
53 #ifndef FVM_PARALLEL
54  if (verbosity >0)
55  cout << 0 << ": " << *rNorm0 << endl;
56 #endif
57 
58 #ifdef FVM_PARALLEL
59  if (verbosity >0 && MPI::COMM_WORLD.Get_rank() == 0)
60  cout << 0 << ": " << *rNorm0 << endl;
61 #endif
62 
63  for(int i = 0; i<nMaxIterations; i++)
64  {
66  rhoPrev = rho;
67  rho = r->dotWith(*rTilda);
68 
69  rho->reduceSum();
70 
71  if (!p)
72  {
73  p = dynamic_pointer_cast<MultiField>(r->newCopy());
74  }
75  else
76  {
77  MFRPtr rhoRatio = (*rho) / (*rhoPrev);
78  MFRPtr alphaByOmega = (*alpha) / (*omega);
79  MFRPtr beta = (*rhoRatio) * (*alphaByOmega);
80  p->msaxpy(*omega,*v);
81  *p *= *beta;
82  *p += *r;
83  }
84 
85  pHat->zero();
86  ls.replaceDelta(pHat);
87  ls.replaceB(p);
88 
90 
91  matrix.multiply(*v,*pHat);
92 
93  MFRPtr rtv = rTilda->dotWith(*v);
94  rtv->reduceSum();
95 
96  alpha = (*rho)/(*rtv);
97 
98  x->msaxpy(*alpha,*pHat);
99  r->msaxpy(*alpha,*v);
100 
101  MFRPtr rNorm = r->getOneNorm();
102 
103  if (*rNorm < absoluteTolerance)
104  {
105  break;
106  }
107 
108  shared_ptr<MultiField> sHat = pHat;
109  sHat->zero();
110  ls.replaceDelta(sHat);
111  ls.replaceB(r);
112 
113  preconditioner->smooth(ls);
114 
115  matrix.multiply(*t,*sHat);
116 
117  MFRPtr tdotr = t->dotWith(*r);
118  MFRPtr tdott = t->dotWith(*t);
119 
120  tdotr->reduceSum();
121  tdott->reduceSum();
122 
123  omega = (*tdotr) / (*tdott);
124 
125  x->msaxpy(*omega,*sHat);
126  r->msaxpy(*omega,*t);
127 
128  rNorm = r->getOneNorm();
129 
130  MFRPtr normRatio(rNorm->normalize(*rNorm0));
131 
132 #ifndef FVM_PARALLEL
133  if (verbosity >0)
134  cout << i+1 << ": " << *rNorm << endl;
135 #endif
136 
137 #ifdef FVM_PARALLEL
138  if (verbosity >0 && MPI::COMM_WORLD.Get_rank() == 0)
139  cout << i+1 << ": " << *rNorm << endl;
140 #endif
141 
142  if (*rNorm < absoluteTolerance || *normRatio < relativeTolerance)
143  break;
144 
145 
146  }
147  ls.replaceDelta(x);
148  ls.replaceB(bOrig);
149 #ifdef FVM_PARALLEL
150  x->sync();
151 #endif
152 
153  matrix.computeResidual(ls.getDelta(),ls.getB(),ls.getResidual());
154  MFRPtr rNormn(ls.getResidual().getOneNorm());
155 
156 #ifndef FVM_PARALLEL
157  if (verbosity >0)
158  cout << "n" << ": " << *rNormn << endl;
159 #endif
160 
161 
162 #ifdef FVM_PARALLEL
163  if (verbosity >0 && MPI::COMM_WORLD.Get_rank() == 0)
164  cout << "n" << ": " << *rNormn << endl;
165 #endif
166 
167 
168 
169  return rNorm0;
170 }
171 
172 void
174 {
175  throw CException("cannot use BCGStab as preconditioner");
176 }
virtual shared_ptr< IContainer > newCopy() const
Definition: MultiField.cpp:101
MultiField & getResidual()
Definition: LinearSystem.h:35
LinearSolver * preconditioner
Definition: BCGStab.h:35
virtual void zero()
Definition: MultiField.cpp:115
void replaceB(shared_ptr< MultiField > newB)
Definition: LinearSystem.h:45
MultiField & getDelta()
Definition: LinearSystem.h:34
MultiField & msaxpy(const MultiFieldReduction &alphaMF, const MultiField &xMF)
Definition: MultiField.cpp:177
virtual void cleanup()=0
int nMaxIterations
Definition: LinearSolver.h:31
shared_ptr< MultiField > getDeltaPtr()
Definition: LinearSystem.h:41
shared_ptr< MultiFieldReduction > getOneNorm() const
Definition: MultiField.cpp:216
double relativeTolerance
Definition: LinearSolver.h:33
virtual void computeResidual(const IContainer &xB, const IContainer &bB, IContainer &rB) const
virtual MFRPtr solve(LinearSystem &ls)
Definition: BCGStab.cpp:27
int _totalIterations
Definition: BCGStab.h:40
virtual void cleanup()
Definition: BCGStab.cpp:21
double absoluteTolerance
Definition: LinearSolver.h:34
MultiField & getB()
Definition: LinearSystem.h:33
virtual void smooth(LinearSystem &ls)
Definition: BCGStab.cpp:173
shared_ptr< MultiFieldReduction > MFRPtr
BCGStab()
Definition: BCGStab.cpp:11
virtual void multiply(IContainer &yB, const IContainer &xB) const
virtual void smooth(LinearSystem &ls)=0
virtual ~BCGStab()
Definition: BCGStab.cpp:16
void replaceDelta(shared_ptr< MultiField > newDelta)
Definition: LinearSystem.h:44
shared_ptr< MultiField > getBPtr()
Definition: LinearSystem.h:42
MultiFieldMatrix & getMatrix()
Definition: LinearSystem.h:37