MultiGrid Class Reference

#include <MultiGrid.hpp>

Inheritance diagram for MultiGrid:

Inheritance graph
[legend]
Collaboration diagram for MultiGrid:

Collaboration graph
[legend]

List of all members.

Public Types

enum  Type {
  none, diagonale, incompleteCholeskiFactorization, multigrid,
  spectralFEM
}

Public Member Functions

std::string name () const
 MultiGrid (const Problem &problem, const SparseMatrix &A, const DegreeOfFreedomSet &degreeOfFreedomSet)
void copyDirichlet (const Vector< real_t > &u, Vector< real_t > &v, const size_t level) const
void residuDirichlet (Vector< real_t > &v, const Vector< real_t > &u1, const Vector< real_t > &u2, const size_t level) const
void setDirichlet (const size_t level, Vector< real_t > &v) const
void getDirichlet (const size_t level, Vector< real_t > &v) const
void interpolateDirichlet (Vector< real_t > &u2, const Vector< real_t > &u1, const size_t currentLevel) const
void restrictDirichlet (const Vector< real_t > &u2, Vector< real_t > &u1, const size_t currentLevel) const
void initializes ()
 Initialization of the Preconditioner.
void weightJacobi (Structured3DVector< real_t > &u, const Structured3DVector< real_t > &b, const size_t currentLevel) const
void computeResidu (Structured3DVector< real_t > &r, const Structured3DVector< real_t > &u, const Structured3DVector< real_t > &f, const size_t currentLevel) const
void correct (Structured3DVector< real_t > &u, const Structured3DVector< real_t > &u2, const size_t currentLevel) const
void project (Structured3DVector< real_t > &u2, const Structured3DVector< real_t > &u, const size_t currentLevel) const
void multigrid (Structured3DVector< real_t > &u, const Structured3DVector< real_t > &b, int currentLevel) const
void FMV (Structured3DVector< real_t > &u, const Structured3DVector< real_t > &b, int currentLevel) const
void computes (const Vector< real_t > &f, Vector< real_t > &v) const
 Computes $ z = P^{-1} r $.
const Preconditioner::TypeType () const
virtual void computesTransposed (const Vector< real_t > &r, Vector< real_t > &z) const
 Computes $ z = P^{-1} r $.

Protected Attributes

Preconditioner::Type __type
 The type of preconditioner.
const Problem__problem

Private Attributes

size_t __level
int nu1
int nu2
int mu1
int mu2
int maxiter
real_t omega
real_t epsilon
const DegreeOfFreedomSet__degreeOfFreedomSet
Structured3DMeshShape __meshShape
GetParameter< MultiGridOptions__options
Structured3DVector< bool > __dirichlet
std::vector
< Structured3DMeshShape
__meshesShape
std::list< DirichletPositions__positionList
std::vector< Vector< real_t > > __dirichletValues

Classes

class  DirichletPositions


Detailed Description

Multi Grid method.

Resolve the linear system #0.
Author:
Stéphane Del Pino.

Definition at line 60 of file MultiGrid.hpp.


Member Enumeration Documentation

enum Preconditioner::Type [inherited]

Enumerator:
none 
diagonale 
incompleteCholeskiFactorization 
multigrid 
spectralFEM 

Definition at line 48 of file Preconditioner.hpp.

00048             {
00049     none,
00050     diagonale,
00051     incompleteCholeskiFactorization,
00052     multigrid,
00053     spectralFEM
00054   };


Constructor & Destructor Documentation

MultiGrid::MultiGrid ( const Problem problem,
const SparseMatrix A,
const DegreeOfFreedomSet degreeOfFreedomSet 
) [inline]

Definition at line 142 of file MultiGrid.hpp.

References __degreeOfFreedomSet, __dirichlet, __dirichletValues, __level, __meshesShape, __meshShape, __options, __positionList, Preconditioner::__problem, Structured3DMeshShape::a(), Structured3DMeshShape::b(), Mesh::cartesianHexahedraMesh, SolverInformationCenter::discretizationType(), MultiGridOptions::epsilon(), epsilon, Structured3DMeshShape::hx(), Structured3DMeshShape::hy(), Structured3DMeshShape::hz(), StaticBase< SolverInformationCenter >::instance(), ScalarDiscretizationTypeBase::lagrangianFEM1, MultiGridOptions::maxiter(), maxiter, SolverInformationCenter::mesh(), MultiGridOptions::mu1(), mu1, MultiGridOptions::mu2(), mu2, ErrorHandler::normal, MultiGridOptions::nu1(), nu1, MultiGridOptions::nu2(), nu2, Structured3DMeshShape::numberOfVertices(), Structured3DVector< T >::nx(), Structured3DMeshShape::nx(), Array3DShape::nx(), Structured3DVector< T >::ny(), Structured3DMeshShape::ny(), Array3DShape::ny(), Structured3DVector< T >::nz(), Structured3DMeshShape::nz(), Array3DShape::nz(), MultiGridOptions::omega(), omega, Structured3DVector< T >::resize(), MultiGrid::DirichletPositions::setPosition(), Structured3DVector< T >::shape(), SpectralMesh::shape(), Structured3DMeshShape::shape(), Structured3DMesh::shape(), DegreeOfFreedomSet::size(), Mesh::spectralMesh, Mesh::type(), and GetParameter< T >::value().

00145     : Preconditioner (problem,
00146                       Preconditioner::multigrid),
00147       __degreeOfFreedomSet(degreeOfFreedomSet),
00148       __meshShape(TinyVector<3,size_t>(0,0,0),
00149                   TinyVector<3,real_t>(-1,-1,-1),
00150                   TinyVector<3,real_t>(1,1,1)),
00151       __dirichlet(Array3DShape(0,0,0))
00152   {
00153     const Mesh& solverMesh = SolverInformationCenter::instance().mesh();
00154     const DiscretizationType& discretization = SolverInformationCenter::instance().discretizationType();
00155     switch (solverMesh.type()) {
00156     case Mesh::cartesianHexahedraMesh: {
00157       const Structured3DMesh& mesh = static_cast<const Structured3DMesh&>(solverMesh);
00158       __meshShape = Structured3DMeshShape(TinyVector<3,size_t>(mesh.shape().shape().nx(),
00159                                                                mesh.shape().shape().ny(),
00160                                                                mesh.shape().shape().nz()),
00161                                           mesh.shape().a(),mesh.shape().b());
00162       __dirichlet.resize(mesh.shape().shape());
00163       break;
00164     }
00165     case Mesh::spectralMesh: {
00166       const SpectralMesh& mesh = static_cast<const SpectralMesh&>(solverMesh);
00167       __meshShape = Structured3DMeshShape(TinyVector<3,size_t>(mesh.shape().shape().nx()-1,
00168                                                                mesh.shape().shape().ny()-1,
00169                                                                mesh.shape().shape().nz()-1),
00170                                           mesh.shape().a(),mesh.shape().b());
00171 //       __meshShape = mesh.shape();
00172       __dirichlet.resize(__meshShape.shape());
00173       break;
00174     }
00175     default: {
00176       throw ErrorHandler(__FILE__,__LINE__,
00177                          "Multigrid does not implemented for this kind of mesh",
00178                          ErrorHandler::normal);      
00179     }
00180     }
00181 
00182     __level = (int)(std::log(real_t(__meshShape.nx()-1))/std::log(2.));
00183 
00184     nu1   = __options.value().nu1();
00185     nu2   = __options.value().nu2();
00186     mu1   = __options.value().mu1();
00187     mu2   = __options.value().mu2();
00188 
00189     epsilon = __options.value().epsilon();
00190     maxiter = __options.value().maxiter();
00191 
00192     omega = __options.value().omega();
00193 
00194     Structured3DMesh mesh(__meshShape,
00195                           new VerticesCorrespondance(__meshShape.numberOfVertices()));
00196 
00197     ReferenceCounting<BoundaryConditionDiscretization>
00198       e = new BoundaryConditionDiscretizationElimination<Structured3DMesh,
00199                                                          ScalarDiscretizationTypeBase::lagrangianFEM1>(__problem,
00200                                                                                                        mesh,
00201                                                                                                        __degreeOfFreedomSet);
00202 
00203 //     ReferenceCounting<BaseMatrix> a = new UnAssembledMatrix(0);
00204 //     ReferenceCounting<BaseVector> b
00205 //       = new Vector<real_t>(__degreeOfFreedomSet.size());
00206 
00207 //     (*e).setSecondMember(a,b);
00208 
00209     for (size_t i=0; i<__degreeOfFreedomSet.size(); ++i) {
00210       __dirichlet[i] = (*e).dirichlet(i);
00211     }
00212 
00213 //     __dirichlet = true;
00214 //     for (size_t i=1; i<__dirichlet.nx()-1; ++i) {
00215 //       for (size_t j=1; j<__dirichlet.ny()-1; ++j) {
00216 //      for (size_t k=1; k<__dirichlet.nz()-1; ++k) {
00217 //        __dirichlet(i,j,k) = false;
00218 
00219 //      }
00220 //       }
00221 //     }    
00222 
00223     __meshesShape.reserve(__level);
00224     __dirichletValues.reserve(__level);
00225 
00226     for (size_t i=0; i<__level; ++i) {
00227       size_t nx = ((__meshShape.nx()-1)/(1<<i))+1;
00228       size_t ny = ((__meshShape.ny()-1)/(1<<i))+1;
00229       size_t nz = ((__meshShape.nz()-1)/(1<<i))+1;
00230 
00231       __meshesShape.push_back(Structured3DMeshShape(TinyVector<3,size_t>(nx,ny,nz),
00232                                                     __meshShape.a(),
00233                                                     __meshShape.b()));
00234     }
00235 
00236     for (size_t i=0; i<__level; ++i) {
00237       __dirichletValues
00238         .push_back(Vector<real_t>(__meshesShape[i].numberOfVertices()));
00239     }
00240 
00241 
00242     for (size_t i=0; i<__dirichlet.nx(); ++i) {
00243       for (size_t j=0; j<__dirichlet.ny(); ++j) {
00244         for (size_t k=0; k<__dirichlet.nz(); ++k) {
00245           if(__dirichlet(i,j,k)) {
00246             DirichletPositions p(__level);
00247             // Stores the first position.
00248             p.setPosition(0, __dirichlet.shape()(i,j,k));
00249 
00250             for(size_t l=1; l<__level; ++l) {
00251               const real_t x = i*__meshShape.hx();
00252               const real_t y = j*__meshShape.hy();
00253               const real_t z = k*__meshShape.hz();
00254 
00255               const size_t I = size_t(rint(x/__meshesShape[l].hx()));
00256               const size_t J = size_t(rint(y/__meshesShape[l].hy()));
00257               const size_t K = size_t(rint(z/__meshesShape[l].hz()));
00258 
00259               p.setPosition(l,__meshesShape[l].shape()(I,J,K));
00260             }
00261             __positionList.push_back(p);
00262           }
00263         }
00264       }
00265     }
00266   }

Here is the call graph for this function:


Member Function Documentation

std::string MultiGrid::name (  )  const [inline, virtual]

Implements Preconditioner.

Definition at line 136 of file MultiGrid.hpp.

00137   {
00138     return "finite differences multigrid";
00139   }

void MultiGrid::copyDirichlet ( const Vector< real_t > &  u,
Vector< real_t > &  v,
const size_t  level 
) const [inline]

Definition at line 268 of file MultiGrid.hpp.

References __level, __meshesShape, __positionList, ASSERT, and Vector< T >::size().

Referenced by weightJacobi().

00271   {
00272     ASSERT(v.size() == __meshesShape[__level-level].numberOfVertices());
00273     ASSERT(u.size() == __meshesShape[__level-level].numberOfVertices());
00274 
00275     for(std::list<DirichletPositions>::const_iterator i
00276           = __positionList.begin();
00277         i != __positionList.end(); ++i) {
00278       size_t j = (*i)(__level-level);
00279       v[j] = u[j];
00280     }
00281   }

Here is the call graph for this function:

void MultiGrid::residuDirichlet ( Vector< real_t > &  v,
const Vector< real_t > &  u1,
const Vector< real_t > &  u2,
const size_t  level 
) const [inline]

Definition at line 283 of file MultiGrid.hpp.

References __level, __meshesShape, __positionList, ASSERT, and Vector< T >::size().

Referenced by computeResidu().

00287   {
00288     ASSERT(v.size() == __meshesShape[__level-level].numberOfVertices());
00289     for(std::list<DirichletPositions>::const_iterator i
00290           = __positionList.begin();
00291         i != __positionList.end(); ++i) {
00292       size_t j = (*i)(__level-level);
00293       v[j] = u1[j] - u2[j];
00294     }
00295   }

Here is the call graph for this function:

void MultiGrid::setDirichlet ( const size_t  level,
Vector< real_t > &  v 
) const [inline]

Definition at line 297 of file MultiGrid.hpp.

References __dirichletValues, __level, and __positionList.

Referenced by computes(), and correct().

00298   {
00299     for(std::list<DirichletPositions>::const_iterator i
00300           = __positionList.begin();
00301         i != __positionList.end(); ++i) {
00302       size_t j = (*i)(__level-level);
00303       v[j] = __dirichletValues[__level-level][j];
00304     }
00305   }

void MultiGrid::getDirichlet ( const size_t  level,
Vector< real_t > &  v 
) const [inline]

Definition at line 307 of file MultiGrid.hpp.

References __dirichletValues, __level, and __positionList.

Referenced by computes(), and correct().

00308   {
00309     for(std::list<DirichletPositions>::const_iterator i
00310           = __positionList.begin();
00311         i != __positionList.end(); ++i) {
00312       size_t j = (*i)(__level-level);
00313       __dirichletValues[__level-level][j] = v[j];
00314     }
00315   }

void MultiGrid::interpolateDirichlet ( Vector< real_t > &  u2,
const Vector< real_t > &  u1,
const size_t  currentLevel 
) const [inline]

Definition at line 317 of file MultiGrid.hpp.

References __level, and __positionList.

Referenced by project().

00320   {
00321     for(std::list<DirichletPositions>::const_iterator i
00322           = __positionList.begin();
00323         i != __positionList.end(); ++i) {
00324       
00325       const size_t i1 = (*i)(__level-currentLevel);
00326       const size_t i2 = (*i)(__level-currentLevel+1);
00327 
00328       u2[i2] = u1[i1];
00329     }
00330     //    getDirichlet(currentLevel-1,u1);
00331   }

void MultiGrid::restrictDirichlet ( const Vector< real_t > &  u2,
Vector< real_t > &  u1,
const size_t  currentLevel 
) const [inline]

Definition at line 333 of file MultiGrid.hpp.

References __level, and __positionList.

00336   {
00337     for(std::list<DirichletPositions>::const_iterator i
00338           = __positionList.begin();
00339         i != __positionList.end(); ++i) {
00340       
00341       const size_t i1 = (*i)(__level-currentLevel);
00342       const size_t i2 = (*i)(__level-currentLevel+1);
00343 
00344       u1[i1] = u2[i2];
00345     }
00346   }

void MultiGrid::initializes (  )  [inline, virtual]

Initialization of the Preconditioner.

Implements Preconditioner.

Definition at line 348 of file MultiGrid.hpp.

00349   {
00350     ;
00351   }

void MultiGrid::weightJacobi ( Structured3DVector< real_t > &  u,
const Structured3DVector< real_t > &  b,
const size_t  currentLevel 
) const [inline]

Definition at line 353 of file MultiGrid.hpp.

References __meshShape, copyDirichlet(), Structured3DMeshShape::dimension(), Array3DShape::nx(), Array3DShape::ny(), Array3DShape::nz(), omega, Structured3DVector< T >::shape(), and Vector< T >::size().

Referenced by multigrid().

00356   {
00357     const Array3DShape& shape = b.shape();
00358 
00359     Vector<real_t> d (u.size());
00360 
00361     real_t dx= __meshShape.dimension(0)/(shape.nx()-1);
00362     real_t dy= __meshShape.dimension(1)/(shape.ny()-1);
00363     real_t dz= __meshShape.dimension(2)/(shape.nz()-1);
00364 
00365     Structured3DVector<real_t> v(u.shape());
00366     v=0;
00367 
00368     for (size_t i=1; i<shape.nx()-1; ++i)
00369       for (size_t j=1; j<shape.ny()-1; ++j)
00370         for (size_t k=1; k<shape.nz()-1; ++k) {
00371           real_t dijk = (2./(dx*dx)+2./(dy*dy)+2./(dz*dz)
00372 //                         +1E5*(pow((i*dx-0.5),2)+pow((j*dy-0.5),2)+pow((k*dz-0.5),2)<0.0625)
00373                          );
00374           v(i,j,k) = ((u(i-1,j,k) + u(i+1,j,k))/(dx*dx)
00375                       + (u(i,j-1,k) + u(i,j+1,k))/(dy*dy)
00376                       + (u(i,j,k-1) + u(i,j,k+1))/(dz*dz)
00377                       + b(i,j,k)
00378                       )/dijk;
00379         }
00380 
00381     copyDirichlet(u,v,currentLevel);
00382 
00383     v *= 1-omega;
00384     u *= omega;
00385     u += v;
00386   }

Here is the call graph for this function:

void MultiGrid::computeResidu ( Structured3DVector< real_t > &  r,
const Structured3DVector< real_t > &  u,
const Structured3DVector< real_t > &  f,
const size_t  currentLevel 
) const [inline]

RECOMPUTE THOSE VALUES !

Definition at line 388 of file MultiGrid.hpp.

References __meshShape, ASSERT, Structured3DMeshShape::dimension(), Structured3DVector< T >::nx(), Structured3DVector< T >::ny(), Structured3DVector< T >::nz(), residuDirichlet(), and Structured3DVector< T >::shape().

Referenced by computes(), FMV(), and multigrid().

00392   {
00394     real_t dx= __meshShape.dimension(0)/(u.nx()-1);
00395     real_t dy= __meshShape.dimension(1)/(u.ny()-1);
00396     real_t dz= __meshShape.dimension(2)/(u.nz()-1);
00397 
00398     r = 0.;
00399 
00400     ASSERT (u.shape()==r.shape());
00401     ASSERT (u.shape()==f.shape());
00402 
00403       for (size_t i=1; i<u.nx()-1; ++i)
00404         for (size_t j=1; j<u.ny()-1; ++j)
00405           for (size_t k=1; k<u.nz()-1; ++k)
00406             r(i,j,k) = 
00407               f(i,j,k)
00408               - (u(i,j,k)*(2./(dx*dx)+2./(dy*dy)+2./(dz*dz)
00409 //                           +1E5*(pow((i*dx-0.5),2)
00410 //                                 +pow((j*dy-0.5),2)
00411 //                                 +pow((k*dz-0.5),2)<0.0625)
00412                            )
00413                  - (u(i-1,j,k) + u(i+1,j,k))/(dx*dx)
00414                  - (u(i,j-1,k) + u(i,j+1,k))/(dy*dy)
00415                  - (u(i,j,k-1) + u(i,j,k+1))/(dz*dz));
00416 
00417       residuDirichlet(r,f,u,currentLevel);
00418   }

Here is the call graph for this function:

void MultiGrid::correct ( Structured3DVector< real_t > &  u,
const Structured3DVector< real_t > &  u2,
const size_t  currentLevel 
) const [inline]

Definition at line 421 of file MultiGrid.hpp.

References ASSERT, getDirichlet(), Structured3DVector< T >::nx(), Structured3DVector< T >::ny(), Structured3DVector< T >::nz(), setDirichlet(), and sum().

Referenced by FMV(), and multigrid().

00424   {
00425 
00426     getDirichlet(currentLevel,u);
00427     ASSERT(u.nx() == ((u2.nx()-1)*2+1));
00428     ASSERT(u.ny() == ((u2.ny()-1)*2+1));
00429     ASSERT(u.nz() == ((u2.nz()-1)*2+1));
00430 
00431     for (size_t i=1; i<u.nx()-1; ++i) {
00432       std::vector<int> indicesI;
00433       indicesI.push_back(i/2);
00434       if (i%2 != 0)
00435         indicesI.push_back(i/2 + 1);
00436       for (size_t j=1; j<u.ny()-1; ++j) {
00437         std::vector<int> indicesJ;
00438         indicesJ.push_back(j/2);
00439         if (j%2 != 0)
00440           indicesJ.push_back(j/2 + 1);
00441         for (size_t k=1; k<u.nz()-1; ++k) {
00442           std::vector<int> indicesK;
00443           indicesK.push_back(k/2);
00444           if (k%2 != 0)
00445             indicesK.push_back(k/2 + 1);
00446 
00447           real_t sum=0;
00448           for (size_t ii=0; ii<indicesI.size(); ++ii) {
00449             for (size_t jj=0; jj<indicesJ.size(); ++jj) {
00450               for (size_t kk=0; kk<indicesK.size(); ++kk) {
00451                 sum += u2(indicesI[ii],indicesJ[jj],indicesK[kk]);
00452               }
00453             }
00454           }
00455           u(i,j,k)
00456             += sum / (indicesI.size()*indicesJ.size()*indicesK.size());
00457         }
00458       }
00459     }
00460     setDirichlet(currentLevel,u);
00461     //    restrictDirichlet(u2,u,currentLevel);
00462   }

Here is the call graph for this function:

void MultiGrid::project ( Structured3DVector< real_t > &  u2,
const Structured3DVector< real_t > &  u,
const size_t  currentLevel 
) const [inline]

Definition at line 464 of file MultiGrid.hpp.

References interpolateDirichlet(), Structured3DVector< T >::nx(), Structured3DVector< T >::ny(), and Structured3DVector< T >::nz().

Referenced by FMV(), and multigrid().

00467   {
00468     //    u2=0;
00469 
00470     real_t c0 = 1./8.;
00471     real_t c1 = 1./16;
00472     real_t c2 = 1./32;
00473     real_t c3 = 1./64;
00474 
00475     for (size_t i=1; i<u2.nx()-1; ++i)
00476       for (size_t j=1; j<u2.ny()-1; ++j)
00477         for (size_t k=1; k<u2.nz()-1; ++k) {
00478           int i1 = 2*i;
00479           int i2 = 2*j;
00480           int i3 = 2*k;
00481 
00482           u2(i,j,k) = c0 * u(i1,i2,i3)
00483             + c1 * ( u(i1-1,i2,  i3  ) + u(i1+1,i2,  i3  )
00484                      +u(i1,  i2-1,i3  ) + u(i1,  i2+1,i3  )
00485                      +u(i1,  i2,  i3-1) + u(i1,  i2,  i3+1) )
00486             + c2 * ( u(i1-1,i2-1,i3  ) + u(i1+1,i2-1,i3  )
00487                      +u(i1-1,i2+1,i3  ) + u(i1+1,i2+1,i3  )
00488                      +u(i1,  i2-1,i3-1) + u(i1,  i2+1,i3-1)
00489                      +u(i1,  i2-1,i3+1) + u(i1,  i2+1,i3+1)
00490                      +u(i1-1,i2,  i3-1) + u(i1-1,i2,  i3+1)
00491                      +u(i1+1,i2,  i3-1) + u(i1+1,i2,  i3+1) )
00492             + c3 * ( u(i1-1,i2-1,i3-1) + u(i1+1,i2-1,i3-1)
00493                      +u(i1-1,i2+1,i3-1) + u(i1+1,i2+1,i3-1)
00494                      +u(i1-1,i2-1,i3+1) + u(i1+1,i2-1,i3+1)
00495                      +u(i1-1,i2+1,i3+1) + u(i1+1,i2+1,i3+1) );
00496         }
00497     interpolateDirichlet(u2,u,currentLevel);
00498   }

Here is the call graph for this function:

void MultiGrid::multigrid ( Structured3DVector< real_t > &  u,
const Structured3DVector< real_t > &  b,
int  currentLevel 
) const [inline]

proceed to some more relaxation for the coasest grid

Definition at line 500 of file MultiGrid.hpp.

References computeResidu(), correct(), mu1, nu1, nu2, Structured3DVector< T >::nx(), Structured3DVector< T >::ny(), Structured3DVector< T >::nz(), project(), Structured3DVector< T >::shape(), and weightJacobi().

Referenced by FMV().

00503   {
00504     Structured3DVector<real_t> r(u.shape());
00505 
00506     for (int i=0; i<nu1; ++i)
00507       weightJacobi(u,b,currentLevel);
00508 
00509     Array3DShape newShape ((u.nx()+1)/2,
00510                            (u.ny()+1)/2,
00511                            (u.nz()+1)/2);
00512 
00513     if (currentLevel > 1) {
00514       
00515       for (int i=0; i<mu1; ++i) { // mu-Cycle
00516         Structured3DVector<real_t> u2(newShape);
00517         u2 = 0;
00518 
00519         Structured3DVector<real_t> b2(newShape);
00520         computeResidu(r,u,b, currentLevel);
00521         
00522         project(b2,r,currentLevel);
00523 
00524         multigrid(u2, b2, currentLevel-1);
00525         correct(u,u2,currentLevel);
00526       }
00527     } else {
00529 #warning Arrange this.
00530       for (size_t i=0; i<nu1+nu2; ++i)
00531         weightJacobi(u,b,currentLevel);
00532     }
00533     for (int i=0; i<nu2; ++i)
00534       weightJacobi(u,b,currentLevel);
00535   }

Here is the call graph for this function:

void MultiGrid::FMV ( Structured3DVector< real_t > &  u,
const Structured3DVector< real_t > &  b,
int  currentLevel 
) const [inline]

Definition at line 537 of file MultiGrid.hpp.

References computeResidu(), correct(), mu2, multigrid(), Structured3DVector< T >::nx(), Structured3DVector< T >::ny(), Structured3DVector< T >::nz(), project(), and Structured3DVector< T >::shape().

Referenced by computes().

00540   {
00541     if (currentLevel > 1) {
00542       Array3DShape newShape ((u.nx()+1)/2,
00543                              (u.ny()+1)/2,
00544                              (u.nz()+1)/2);
00545 
00546       Structured3DVector<real_t> r(u.shape());
00547 
00548       Structured3DVector<real_t> u2(newShape);
00549       u2 = 0;
00550 
00551       Structured3DVector<real_t> b2(newShape);
00552       computeResidu(r,u,b,currentLevel);
00553       project(b2,r,currentLevel);
00554 
00555       FMV(u2, b2, currentLevel-1);
00556       correct(u,u2,currentLevel);
00557     }
00558 
00559     for (int i=0; i<mu2; ++i)
00560       multigrid(u,b,currentLevel);
00561   }

Here is the call graph for this function:

void MultiGrid::computes ( const Vector< real_t > &  r,
Vector< real_t > &  z 
) const [inline, virtual]

Computes $ z = P^{-1} r $.

Implements Preconditioner.

Definition at line 563 of file MultiGrid.hpp.

References __level, __meshShape, ASSERT, computeResidu(), epsilon, ffout(), FMV(), getDirichlet(), Structured3DMeshShape::hx(), Structured3DMeshShape::hy(), Structured3DMeshShape::hz(), maxiter, setDirichlet(), Structured3DVector< T >::shape(), Structured3DMeshShape::shape(), and Vector< T >::size().

Referenced by SpectralFEMPreconditioner::Internal::__solveFEM().

00565   {
00566     Structured3DVector<real_t> u(__meshShape.shape());
00567     Structured3DVector<real_t> b(__meshShape.shape());
00568 
00569     ASSERT(u.size() == v.size());
00570     ASSERT(b.size() == f.size());
00571 
00572     u = v;
00573     b = f;
00574 
00575     real_t dx = __meshShape.hx();
00576     real_t dy = __meshShape.hy();
00577     real_t dz = __meshShape.hz();
00578 
00579 //     std::cout << "multigrid dxi = "<< dx << 'x' << dy << 'x' << dz << '\n';
00580 
00581 //     real_t pi = std::atan(1.)*4.;
00582 
00583 //     for (size_t i=0; i<b.nx(); ++i)
00584 //       for (size_t j=0; j<b.ny(); ++j)
00585 //      for (size_t k=0; k<b.nz(); ++k) {
00586 //        b(i,j,k) = std::sin(pi*i*__meshShape.hx());
00587 //      }
00588 //     v = b;
00589 //     for (size_t i=1; i<b.nx()-1; ++i)
00590 //       for (size_t j=1; j<b.ny()-1; ++j)
00591 //      for (size_t k=1; k<b.nz()-1; ++k) {
00592 //        real_t x = i*__meshShape.hx();
00593 //        b(i,j,k) = pi*pi*std::sin(pi*x);
00594 //      }
00595 
00596     getDirichlet(__level,b);
00597 
00598      //     b *= 1./(dx*dy*dz);
00599 
00600     // inside the domain 2nd member should be rescaled
00601     // for compatibility between FEM and FDM.
00602 //     for (size_t i=1; i<b.nx()-1; ++i)
00603 //       for (size_t j=1; j<b.ny()-1; ++j)
00604 //      for (size_t k=1; k<b.nz()-1; ++k) {
00605 //        b(i,j,k) /= dx*dy*dz;
00606 //        //      u(i,j,k) = 0;
00607 //      }
00608 
00609 //     for (size_t i=1; i<b.nx()-1; ++i)
00610 //       for (size_t j=1; j<b.ny()-1; ++j)
00611 //      for (size_t k=1; k<b.nz()-1; ++k) {
00612 //        u(i,j,k) = 0;
00613 //      }
00614 
00615 //     for (size_t i=1; i<b.nx()-1; ++i)
00616 //       for (size_t j=1; j<b.ny()-1; ++j)
00617 //      for (size_t k=1; k<b.nz()-1; ++k) {
00618 //        b(i,j,k) /= dx*dy*dz*dx*dy*dz;
00619 //      }
00620 //    b *= (dx*dy*dz)*(dx*dy*dz);
00621     u=0;
00622 
00623     setDirichlet(__level,u);
00624     setDirichlet(__level,b);
00625 
00626     Structured3DVector<real_t> r(u);
00627     computeResidu(r,u,b,__level);
00628 
00629     real_t resid0 = Norm(r);
00630 
00631     real_t norm;
00632     int n = 0;
00633     /*
00634     for (size_t i=0; i<10; ++i) {
00635       weightJacobi(u,b,__level);
00636 
00637       computeResidu(r,u,b,__level);
00638       real_t resid = Norm(r);
00639 
00640       ffout(4) << "\tFMG norme:" << resid << '\n';
00641     }
00642     */
00643 //     computeResidu(r,u,b,__level);
00644 //     ffout(0) << "\tFMG norme:" << Norm(r) << "\n";
00645 
00646     do {
00647       FMV(u, b, __level);
00648 
00649       computeResidu(r,u,b,__level);
00650 
00651       real_t resid = Norm(r);
00652 
00653       norm = resid/resid0;
00654       ffout(0) << "\tFMG norme:" << norm <<" (" << resid << '/' << resid0 << ")\n";
00655       n++;
00656     } while ((norm>epsilon) and (n<maxiter));
00657 
00658     for (size_t i=1; i<b.nx()-1; ++i)
00659       for (size_t j=1; j<b.ny()-1; ++j)
00660         for (size_t k=1; k<b.nz()-1; ++k) {
00661           v[u.shape()(i,j,k)] = u(i,j,k);
00662 //        b(i,j,k) /= dx*dy*dz*dx*dy*dz;
00663         }
00664 //     std::cout << "Norm(u)=" << Norm(u) << '\n';
00665   }

Here is the call graph for this function:

const Preconditioner::Type& Preconditioner::Type (  )  const [inline, inherited]

Definition at line 100 of file Preconditioner.hpp.

References Preconditioner::__type.

00101   {
00102     return __type;
00103   }

virtual void Preconditioner::computesTransposed ( const Vector< real_t > &  r,
Vector< real_t > &  z 
) const [inline, virtual, inherited]

Computes $ z = P^{-1} r $.

Reimplemented in SpectralFEMPreconditioner.

Definition at line 72 of file Preconditioner.hpp.

References Preconditioner::computes().

00074   {
00075     this->computes(r,z);
00076   }

Here is the call graph for this function:


Member Data Documentation

size_t MultiGrid::__level [mutable, private]

int MultiGrid::nu1 [private]

Definition at line 112 of file MultiGrid.hpp.

Referenced by multigrid(), and MultiGrid().

int MultiGrid::nu2 [private]

Definition at line 113 of file MultiGrid.hpp.

Referenced by multigrid(), and MultiGrid().

int MultiGrid::mu1 [private]

Definition at line 114 of file MultiGrid.hpp.

Referenced by multigrid(), and MultiGrid().

int MultiGrid::mu2 [private]

Definition at line 115 of file MultiGrid.hpp.

Referenced by FMV(), and MultiGrid().

int MultiGrid::maxiter [private]

Definition at line 117 of file MultiGrid.hpp.

Referenced by computes(), and MultiGrid().

real_t MultiGrid::omega [private]

Definition at line 119 of file MultiGrid.hpp.

Referenced by MultiGrid(), and weightJacobi().

real_t MultiGrid::epsilon [private]

Definition at line 120 of file MultiGrid.hpp.

Referenced by computes(), and MultiGrid().

Definition at line 122 of file MultiGrid.hpp.

Referenced by MultiGrid().

Definition at line 124 of file MultiGrid.hpp.

Referenced by computeResidu(), computes(), MultiGrid(), and weightJacobi().

Definition at line 126 of file MultiGrid.hpp.

Referenced by MultiGrid().

Definition at line 128 of file MultiGrid.hpp.

Referenced by MultiGrid().

Definition at line 130 of file MultiGrid.hpp.

Referenced by copyDirichlet(), MultiGrid(), and residuDirichlet().

std::vector<Vector<real_t> > MultiGrid::__dirichletValues [mutable, private]

Definition at line 133 of file MultiGrid.hpp.

Referenced by getDirichlet(), MultiGrid(), and setDirichlet().

The type of preconditioner.

Definition at line 58 of file Preconditioner.hpp.

Referenced by Preconditioner::Type().

const Problem& Preconditioner::__problem [protected, inherited]

Definition at line 61 of file Preconditioner.hpp.

Referenced by SpectralFEMPreconditioner::initializes(), and MultiGrid().


The documentation for this class was generated from the following file:

Generated on Wed Nov 19 00:10:31 2008 for FreeFEM3D (aka ff3d) by  doxygen 1.5.6