SpectralFEMPreconditioner::Internal Class Reference

Collaboration diagram for SpectralFEMPreconditioner::Internal:

Collaboration graph
[legend]

List of all members.

Public Member Functions

 Internal (const Problem &problem)
void computes (const Vector< real_t > &r, Vector< real_t > &z) const
void computesTransposed (const Vector< real_t > &r, Vector< real_t > &z) const

Private Member Functions

template<typename MeshType>
void __solveFEM (ConstReferenceCounting< MeshType > mesh, Structured3DVector< real_t > &lagrange) const
void __legendreToLagrange (const Structured3DVector< real_t > &legendre, Structured3DVector< real_t > &lagrange) const
void __legendreToLagrangeTransposed (const Structured3DVector< real_t > &lagrange, Structured3DVector< real_t > &legendre) const
void __lagrangeToLegendre (const Structured3DVector< real_t > &lagrange, Structured3DVector< real_t > &legendre) const
void __lagrangeToLegendreTransposed (const Structured3DVector< real_t > &legendre, Structured3DVector< real_t > &lagrange) const
void __residuToLegendre (const Structured3DVector< real_t > &residu, Structured3DVector< real_t > &legendre) const
void __legendreToResidu (const Structured3DVector< real_t > &legendre, Structured3DVector< real_t > &residu) const

Private Attributes

const Problem__problem
TinyVector< 3, size_t > __legendreDegrees
TinyVector< 3, size_t > __legendreDimensions
TinyVector< 3, size_t > __lagrangeDegrees
TinyVector< 3, size_t > __lagrangeDimensions
TinyVector< 3, real_t > __a
TinyVector< 3, real_t > __b
TinyVector< 3, Vector< real_t > > __lagrangeVertices


Detailed Description

Definition at line 60 of file SpectralFEMPreconditioner.cpp.


Constructor & Destructor Documentation

SpectralFEMPreconditioner::Internal::Internal ( const Problem problem  )  [inline]

Constructor

Parameters:
problem problem to precondition

Definition at line 708 of file SpectralFEMPreconditioner.cpp.

00709     : __problem(problem)
00710   {
00711     ;
00712   }


Member Function Documentation

template<typename MeshType>
void SpectralFEMPreconditioner::Internal::__solveFEM ( ConstReferenceCounting< MeshType >  mesh,
Structured3DVector< real_t > &  lagrange 
) const [inline, private]

Definition at line 77 of file SpectralFEMPreconditioner.cpp.

References __problem, DiscretizationType::add(), VariationalProblem::add(), FEMFunctionBuilder::build(), MultiGrid::computes(), DegreeOfFreedomSetBuilder::degreeOfFreedomSet(), BaseMatrix::doubleHashedMatrix, ffout(), FEMFunctionBuilder::getBuiltScalarFunction(), StaticBase< ParameterCenter >::instance(), ScalarDiscretizationTypeBase::lagrangianFEM1, VariationalOperator::normal, VariationalProblem::numberOfUnknown(), MemoryManager::ReserveMatrix(), ParameterCenter::set(), DegreeOfFreedomSet::size(), Timer::start(), Timer::stop(), Problem::type(), ErrorHandler::unexpected, and Problem::variational.

00079   {
00080     ParameterCenter::instance().set("memory::matrix", "sparse");
00081 
00082     if (__problem.type() != Problem::variational) {
00083       throw ErrorHandler(__FILE__,__LINE__,
00084                          "not yet implemented",
00085                          ErrorHandler::unexpected);
00086     }
00087 
00088     VariationalProblem femProblem(dynamic_cast<const VariationalProblem&>(__problem), true);
00089 
00090     FEMFunctionBuilder builder;
00091     builder.build(ScalarDiscretizationTypeFEM(ScalarDiscretizationTypeBase::lagrangianFEM1),
00092                   mesh,
00093                   lagrange);
00094 
00095     femProblem.add(new VariationalOperatorFV(0,VariationalOperator::normal, builder.getBuiltScalarFunction()));
00096     
00097     DiscretizationType discretization;
00098     for (size_t i=0; i<femProblem.numberOfUnknown(); ++i) {
00099       discretization.add(new ScalarDiscretizationTypeFEM(ScalarDiscretizationTypeBase::lagrangianFEM1));
00100     }
00101 
00102     DegreeOfFreedomSetBuilder dofBuilder(discretization,
00103                                          *mesh);
00104     const DegreeOfFreedomSet& degreeOfFreedomSet
00105       = dofBuilder.degreeOfFreedomSet();
00106 
00107     MemoryManager MM;
00108     ReferenceCounting<BaseMatrix> femA;
00109 
00110     bool performAssembling =MM.ReserveMatrix(femA,
00111                                              femProblem.numberOfUnknown(),
00112                                              degreeOfFreedomSet.size());
00113 
00114 //     ReferenceCounting<BaseVector> femB;
00115 //     MM.ReserveVector(femB,
00116 //                   femProblem.numberOfUnknown(),
00117 //                   degreeOfFreedomSet.size());
00118 
00119 //     ffout(0) << "Finite element method: disretization...\n";
00120 
00121 //     ReferenceCounting<FEMDiscretization<MeshType,
00122 //       ScalarDiscretizationTypeBase::lagrangianFEM1> > FEM
00123 //       = new FEMDiscretization<MeshType,
00124 //       ScalarDiscretizationTypeBase::lagrangianFEM1>(femProblem,
00125 //                                                  *mesh,
00126 //                                                  discretization,
00127 //                                                  *femA, *femB, degreeOfFreedomSet);
00128 
00129 //     if (performAssembling) {
00130 //       FEM->assembleMatrix();
00131 //     } else {
00132 //       ffout(4) << "- keeping previous operator discretization\n";
00133 //     }
00134 
00135 //     FEM->assembleSecondMember();
00136 
00137 
00138 //     ffout(4) << "- discretizing boundary conditions\n";
00139 
00140 //     BoundaryConditionDiscretizationFEM<MeshType,
00141 //       ScalarDiscretizationTypeBase::lagrangianFEM1>* bcd
00142 //       = new BoundaryConditionDiscretizationFEM<MeshType,
00143 //       ScalarDiscretizationTypeBase::lagrangianFEM1>(femProblem,
00144 //                                                  *mesh,
00145 //                                                  degreeOfFreedomSet);
00146 //     bcd->associatesMeshesToBoundaryConditions();
00147 //     ReferenceCounting<BoundaryConditionDiscretization> bcDiscretization = bcd;
00148 
00149 //     // Set Dirichlet information to the matrix
00150 //     FEM->setDirichletList(bcDiscretization->getDirichletList());
00151 
00152 //     ffout(4) << "- second member modification\n";
00153 //     bcDiscretization->setSecondMember(femA,femB);
00154 
00155 //     ffout(4) << "- matrix modification\n";
00156 //     bcDiscretization->setMatrix(femA,femB);
00157 
00158 //     ffout(4) << "Finite element method: disretization done\n";
00159 
00160     if (femA->type() == BaseMatrix::doubleHashedMatrix) {
00161       Timer t;
00162       t.start();
00163 
00164       SparseMatrix* aa
00165         = new SparseMatrix(static_cast<DoubleHashedMatrix&>(*femA));
00166     
00167       femA = aa; // now use sparse matrix
00168 
00169       t.stop();
00170       ffout(4) << "Matrix copy: " << t << '\n';
00171     }
00172 
00173 //     ReferenceCounting<Preconditioner> P = new IdentityPrecond(femProblem);
00174 
00175 //     lagrange = 0;
00176 
00177     Structured3DVector<real_t> residu(lagrange);
00178     MultiGrid M(__problem,static_cast<const SparseMatrix&>(*femA),degreeOfFreedomSet);
00179     M.computes(residu,lagrange);
00180     //    static_cast<Vector<real_t>&>(*femB)=0;
00181 //     ffout(4) << "- FEM CG\n";
00182 //     ConjugateGradient cg(static_cast<Vector<real_t>&>(*femB),
00183 //                       *femA, *P,
00184 //                       static_cast<Vector<real_t>&>(lagrange),500,1E-2);
00185 //     //    lagrange = static_cast<Vector<real_t>&>(*femB);
00186 //     ffout(4) << "- FEM CG: done\n"; 
00187   }

Here is the call graph for this function:

void SpectralFEMPreconditioner::Internal::__legendreToLagrange ( const Structured3DVector< real_t > &  legendre,
Structured3DVector< real_t > &  lagrange 
) const [inline, private]

Definition at line 190 of file SpectralFEMPreconditioner.cpp.

References __lagrangeDimensions, __lagrangeVertices, __legendreDegrees, __legendreDimensions, and Vector< T >::size().

Referenced by computes().

00192   {
00193     lagrange = 0;
00194     
00195     TinyVector<3, ConstReferenceCounting<LegendreBasis> > legendreBasis;
00196     for (size_t i=0; i<3; ++i) {
00197       legendreBasis[i] = new LegendreBasis(__legendreDegrees[i]);
00198     }
00199 
00200     TinyVector<3,Vector<Vector<real_t> > >  legendreBaseValues;
00201     for (size_t i=0; i<3; ++i) {
00202       legendreBaseValues[i].resize(__lagrangeVertices[i].size());
00203     }
00204 
00205     for(size_t i=0; i<3; ++i) {
00206       const Vector<real_t> vertices = __lagrangeVertices[i];
00207       for(size_t j=0; j<vertices.size(); ++j){
00208         // Compute position of vertex j in direction i
00209         const real_t& xj = vertices[j];
00210 
00211         legendreBaseValues[i][j].resize(legendreBasis[i]->dimension());
00212         legendreBasis[i]->getValues(xj,legendreBaseValues[i][j]);
00213       }
00214     }
00215 
00216     const Structured3DVector<real_t>& u_ijk = legendre;
00217 
00218     Structured3DVector<real_t> u_ijt(Array3DShape(__legendreDimensions[0],
00219                                                   __legendreDimensions[1],
00220                                                   __lagrangeDimensions[2]));
00221     u_ijt=0;
00222 
00223     {
00224       for (size_t i=0; i< __legendreDimensions[0]; ++i) {
00225         for (size_t j=0; j< __legendreDimensions[1]; ++j) {
00226           for (size_t k=0; k< __legendreDimensions[2]; ++k) {
00227             const real_t& u_ijk_value = u_ijk(i,j,k);
00228             for (size_t t=0; t< __lagrangeDimensions[2]; ++t) {
00229               u_ijt(i,j,t) += u_ijk_value * legendreBaseValues[2][t][k];
00230             }
00231           }
00232         }
00233       }
00234     }
00235 
00236     Structured3DVector<real_t> u_ist(Array3DShape(__legendreDimensions[0],
00237                                                   __lagrangeDimensions[1],
00238                                                   __lagrangeDimensions[2]));
00239     u_ist=0;
00240 
00241     for (size_t i=0; i<__legendreDimensions[0]; ++i) {
00242       for (size_t j=0; j<__legendreDimensions[1]; ++j) {
00243         for (size_t t=0; t<__lagrangeDimensions[2]; ++t) {
00244           const real_t& u_ijt_value = u_ijt(i,j,t);
00245           for (size_t s=0; s<__lagrangeDimensions[1]; ++s) {
00246             u_ist(i,s,t) += u_ijt_value*legendreBaseValues[1][s][j];
00247           }
00248         }
00249       }
00250     }
00251 
00252     Structured3DVector<real_t>& u_rst = lagrange;
00253     u_rst=0;
00254     
00255     for (size_t i=0; i<__legendreDimensions[0]; ++i) {
00256       for (size_t s=0; s<__lagrangeDimensions[1]; ++s) {
00257         for (size_t t=0; t<__lagrangeDimensions[2]; ++t) {
00258           const real_t& u_ist_value = u_ist(i,s,t);
00259           for (size_t r=0; r<__lagrangeDimensions[0]; ++r) {
00260             u_rst(r,s,t) += u_ist_value*legendreBaseValues[0][r][i];
00261           }
00262         }
00263       }
00264     }
00265   }

Here is the call graph for this function:

void SpectralFEMPreconditioner::Internal::__legendreToLagrangeTransposed ( const Structured3DVector< real_t > &  lagrange,
Structured3DVector< real_t > &  legendre 
) const [inline, private]

Definition at line 267 of file SpectralFEMPreconditioner.cpp.

References __lagrangeDimensions, __lagrangeVertices, __legendreDegrees, __legendreDimensions, and Vector< T >::size().

Referenced by computesTransposed().

00269   {
00270     legendre = 0;
00271     
00272     TinyVector<3, ConstReferenceCounting<LegendreBasis> > legendreBasis;
00273     for (size_t i=0; i<3; ++i) {
00274       legendreBasis[i] = new LegendreBasis(__legendreDegrees[i]);
00275     }
00276 
00277     TinyVector<3,Vector<Vector<real_t> > >  legendreBaseValues;
00278     for (size_t i=0; i<3; ++i) {
00279       legendreBaseValues[i].resize(__lagrangeVertices[i].size());
00280     }
00281 
00282     for(size_t i=0; i<3; ++i) {
00283       const Vector<real_t> vertices = __lagrangeVertices[i];
00284       for(size_t j=0; j<vertices.size(); ++j){
00285         // Compute position of vertex j in direction i
00286         const real_t& xj = vertices[j];
00287 
00288         legendreBaseValues[i][j].resize(legendreBasis[i]->dimension());
00289         legendreBasis[i]->getValues(xj,legendreBaseValues[i][j]);
00290       }
00291     }
00292 
00293     const Structured3DVector<real_t>& u_rst = lagrange;
00294 
00295     Structured3DVector<real_t> u_rsk(Array3DShape(__lagrangeDimensions[0],
00296                                                   __lagrangeDimensions[1],
00297                                                   __legendreDimensions[2]));
00298     u_rsk=0;
00299 
00300     {
00301       for (size_t r=0; r< __lagrangeDimensions[0]; ++r) {
00302         for (size_t s=0; s< __lagrangeDimensions[1]; ++s) {
00303           for (size_t t=0; t< __lagrangeDimensions[2]; ++t) {
00304             const real_t& u_rst_value = u_rst(r,s,t);
00305             for (size_t k=0; k< __legendreDimensions[2]; ++k) {
00306               u_rsk(r,s,k) += u_rst_value * legendreBaseValues[2][t][k];
00307             }
00308           }
00309         }
00310       }
00311     }
00312 
00313     Structured3DVector<real_t> u_rjk(Array3DShape(__lagrangeDimensions[0],
00314                                                   __legendreDimensions[1],
00315                                                   __legendreDimensions[2]));
00316     u_rjk=0;
00317 
00318     for (size_t r=0; r<__lagrangeDimensions[0]; ++r) {
00319       for (size_t s=0; s<__lagrangeDimensions[1]; ++s) {
00320         for (size_t k=0; k<__legendreDimensions[2]; ++k) {
00321           const real_t& u_rsk_value = u_rsk(r,s,k);
00322           for (size_t j=0; j<__legendreDimensions[1]; ++j) {
00323             u_rjk(r,j,k) += u_rsk_value*legendreBaseValues[1][s][j];
00324           }
00325         }
00326       }
00327     }
00328 
00329     Structured3DVector<real_t>& u_ijk = legendre;
00330     u_ijk=0;
00331     
00332     for (size_t r=0; r<__lagrangeDimensions[0]; ++r) {
00333       for (size_t j=0; j<__legendreDimensions[1]; ++j) {
00334         for (size_t k=0; k<__legendreDimensions[2]; ++k) {
00335           const real_t& u_rjk_value = u_rjk(r,j,k);
00336           for (size_t i=0; i<__legendreDimensions[0]; ++i) {
00337             u_ijk(i,j,k) += u_rjk_value*legendreBaseValues[0][r][i];
00338           }
00339         }
00340       }
00341     }
00342   }

Here is the call graph for this function:

void SpectralFEMPreconditioner::Internal::__lagrangeToLegendre ( const Structured3DVector< real_t > &  lagrange,
Structured3DVector< real_t > &  legendre 
) const [inline, private]

Taking into account of the renormalization of the legendre polynomials

Definition at line 344 of file SpectralFEMPreconditioner.cpp.

References __lagrangeDegrees, __lagrangeDimensions, __lagrangeVertices, __legendreDegrees, __legendreDimensions, GaussLobattoManager::getReference(), StaticBase< GaussLobattoManager >::instance(), and GaussLobatto::numberOfPoints().

Referenced by computes().

00346   {
00347     legendre = 0;
00348     
00349     TinyVector<3, ConstReferenceCounting<LegendreBasis> > legendreBasis;
00350     TinyVector<3, ConstReferenceCounting<LagrangeBasis> > lagrangeBasis;
00351     for (size_t i=0; i<3; ++i) {
00352       legendreBasis[i] = new LegendreBasis(__legendreDegrees[i]);
00353       lagrangeBasis[i] = new LagrangeBasis(__lagrangeVertices[i]);
00354     }
00355     
00356     TinyVector<3, ConstReferenceCounting<GaussLobatto> > gaussLobatto;
00357     for (size_t i=0; i<3; ++i) {
00358       gaussLobatto[i] = GaussLobattoManager::instance().getReference((__legendreDegrees[i]+__lagrangeDegrees[i]) + 1);
00359     }
00360 
00361     TinyVector<3,Vector<Vector<real_t> > >  legendreBaseValues;
00362     TinyVector<3,Vector<Vector<real_t> > >  lagrangeBaseValues;
00363     for (size_t i=0; i<3; ++i) {
00364       legendreBaseValues[i].resize(gaussLobatto[i]->numberOfPoints());
00365       lagrangeBaseValues[i].resize(gaussLobatto[i]->numberOfPoints());
00366     }
00367     
00368     for(size_t i=0; i<3; ++i) {
00369       const GaussLobatto& gaussLobattoPoints = *gaussLobatto[i];
00370       for(size_t j=0; j<gaussLobattoPoints.numberOfPoints(); ++j){
00371         
00372         // Compute position of vertex j in direction i
00373         const real_t& xj = gaussLobattoPoints(j);
00374         
00375         legendreBaseValues[i][j].resize(legendreBasis[i]->dimension());
00376         legendreBasis[i]->getValues(xj,legendreBaseValues[i][j]);
00377         
00378         lagrangeBaseValues[i][j].resize(lagrangeBasis[i]->dimension());
00379         lagrangeBasis[i]->getValues(xj,lagrangeBaseValues[i][j]);
00380       }
00381     }
00382     
00383     Structured3DVector<real_t> u_r0s0t(Array3DShape(__lagrangeDimensions[0],
00384                                                     __lagrangeDimensions[1],
00385                                                     gaussLobatto[2]->numberOfPoints()));
00386     u_r0s0t = 0;
00387     
00388     {
00389       for (size_t r0=0; r0 < __lagrangeDimensions[0]; ++r0) {
00390         for (size_t s0=0; s0 < __lagrangeDimensions[1]; ++s0) {
00391           for (size_t t0=0; t0 < __lagrangeDimensions[2]; ++t0) {
00392             const real_t& u_r0s0t0_value = lagrange(r0,s0,t0);
00393             for (size_t t=0; t< gaussLobatto[2]->numberOfPoints(); ++t) {
00394               u_r0s0t(r0,s0,t) += u_r0s0t0_value * lagrangeBaseValues[2][t][t0] ;
00395             }
00396           }
00397         }
00398       }
00399     }
00400     
00401     Structured3DVector<real_t> u_r0st(Array3DShape(__lagrangeDimensions[0],
00402                                                    gaussLobatto[1]->numberOfPoints(),
00403                                                    gaussLobatto[2]->numberOfPoints()));
00404     u_r0st = 0;
00405     
00406     {
00407       for (size_t r0=0; r0 <__lagrangeDimensions[0]; ++r0) {
00408         for (size_t s0=0; s0 <__lagrangeDimensions[1]; ++s0) {
00409           for (size_t t=0; t < gaussLobatto[2]->numberOfPoints(); ++t) {
00410             const real_t& u_r0s0t_value = u_r0s0t(r0,s0,t) ;
00411             for (size_t s=0; s<gaussLobatto[1]->numberOfPoints(); ++s) {
00412               u_r0st(r0,s,t) += u_r0s0t_value * lagrangeBaseValues[1][s][s0];
00413             }
00414           }
00415         }
00416       }
00417     }
00418     
00419     Structured3DVector<real_t> u_rst(Array3DShape(gaussLobatto[0]->numberOfPoints(),
00420                                                   gaussLobatto[1]->numberOfPoints(),
00421                                                   gaussLobatto[2]->numberOfPoints()));
00422     u_rst = 0;
00423     {
00424       for (size_t r0=0; r0 < __lagrangeDimensions[0]; ++r0) {
00425         for (size_t s=0; s <gaussLobatto[1]->numberOfPoints(); ++s) {
00426           for (size_t t=0; t <gaussLobatto[2]->numberOfPoints(); ++t) {
00427             const real_t& u_r0st_value = u_r0st(r0,s,t);
00428             for (size_t r=0; r<gaussLobatto[0]->numberOfPoints(); ++r) {
00429               u_rst(r,s,t) += u_r0st_value * lagrangeBaseValues[0][r][r0];
00430             }
00431           }
00432         }
00433       }
00434     }
00435 
00436     Structured3DVector<real_t> u_rsk(Array3DShape(gaussLobatto[0]->numberOfPoints(),
00437                                                   gaussLobatto[1]->numberOfPoints(),
00438                                                   __legendreDimensions[2]));
00439     u_rsk = 0;
00440     
00441     {
00442       for (size_t r=0; r < gaussLobatto[0]->numberOfPoints(); ++r) {
00443         for (size_t s=0; s < gaussLobatto[1]->numberOfPoints(); ++s) {
00444           for (size_t t=0; t < gaussLobatto[2]->numberOfPoints(); ++t) {
00445             const real_t& wt = gaussLobatto[2]->weight(t);
00446             const real_t u_rst_value = u_rst(r,s,t) * wt;
00447             for (size_t k=0; k<__legendreDimensions[2]; ++k) {
00448               u_rsk(r,s,k) += u_rst_value * legendreBaseValues[2][t][k];
00449             }
00450           }
00451         }
00452       }
00453     }
00454     
00455     Structured3DVector<real_t> u_rjk(Array3DShape(gaussLobatto[0]->numberOfPoints(),
00456                                                   __legendreDimensions[1],
00457                                                   __legendreDimensions[2]));
00458     u_rjk = 0;
00459     
00460     {
00461       for (size_t r=0; r < gaussLobatto[0]->numberOfPoints(); ++r) {
00462         for (size_t s=0; s < gaussLobatto[1]->numberOfPoints(); ++s) {
00463           const real_t& ws = gaussLobatto[1]->weight(s);
00464           for (size_t k=0; k < __legendreDimensions[2]; ++k) {
00465             const real_t u_rsk_value = u_rsk(r,s,k) * ws;
00466             for (size_t j=0; j<__legendreDimensions[1]; ++j) {
00467               u_rjk(r,j,k) += u_rsk_value * legendreBaseValues[1][s][j];
00468             }
00469           }
00470         }
00471       }
00472     }
00473     
00474     Structured3DVector<real_t>& u_ijk = legendre;
00475     {
00476       for (size_t r=0; r < gaussLobatto[0]->numberOfPoints(); ++r) {
00477         const real_t& wr = gaussLobatto[0]->weight(r);
00478         for (size_t j=0; j < __legendreDimensions[1]; ++j) {
00479           for (size_t k=0; k < __legendreDimensions[2]; ++k) {
00480             const real_t u_rjk_value = u_rjk(r,j,k) * wr;
00481             for (size_t i=0; i<__legendreDimensions[0]; ++i) {
00482               u_ijk(i,j,k) += u_rjk_value * legendreBaseValues[0][r][i];
00483             }
00484           }
00485         }
00486       }
00487     }
00488     
00489     //    return;
00493     for (size_t i=0; i < __legendreDimensions[0]; ++i) {
00494       const real_t wi_8 = 1./8 * (2*i+1);
00495       for (size_t j=0;j < __legendreDimensions[1]; ++j) { 
00496         const real_t wi_wj_8 = wi_8 * (2*j+1);
00497         for (size_t k=0; k < __legendreDimensions[2]; ++k) {
00498           const real_t wi_wj_wk_8 = wi_wj_8 * (2*k+1);
00499           u_ijk(i,j,k) *= wi_wj_wk_8 ;
00500         }
00501       }
00502     }
00503   }

Here is the call graph for this function:

void SpectralFEMPreconditioner::Internal::__lagrangeToLegendreTransposed ( const Structured3DVector< real_t > &  legendre,
Structured3DVector< real_t > &  lagrange 
) const [inline, private]

Taking into account of the renormalization of the legendre polynomials

Definition at line 505 of file SpectralFEMPreconditioner.cpp.

References __lagrangeDegrees, __lagrangeDimensions, __lagrangeVertices, __legendreDegrees, __legendreDimensions, GaussLobattoManager::getReference(), StaticBase< GaussLobattoManager >::instance(), and GaussLobatto::numberOfPoints().

Referenced by computesTransposed().

00507   {
00508     lagrange = 0;
00509     
00510     TinyVector<3, ConstReferenceCounting<LegendreBasis> > legendreBasis;
00511     TinyVector<3, ConstReferenceCounting<LagrangeBasis> > lagrangeBasis;
00512     for (size_t i=0; i<3; ++i) {
00513       legendreBasis[i] = new LegendreBasis(__legendreDegrees[i]);
00514       lagrangeBasis[i] = new LagrangeBasis(__lagrangeVertices[i]);
00515     }
00516     
00517     TinyVector<3, ConstReferenceCounting<GaussLobatto> > gaussLobatto;
00518     for (size_t i=0; i<3; ++i) {
00519       gaussLobatto[i] = GaussLobattoManager::instance().getReference((__legendreDegrees[i]+__lagrangeDegrees[i]) + 1);
00520     }
00521 
00522     TinyVector<3,Vector<Vector<real_t> > >  legendreBaseValues;
00523     TinyVector<3,Vector<Vector<real_t> > >  lagrangeBaseValues;
00524     for (size_t i=0; i<3; ++i) {
00525       legendreBaseValues[i].resize(gaussLobatto[i]->numberOfPoints());
00526       lagrangeBaseValues[i].resize(gaussLobatto[i]->numberOfPoints());
00527     }
00528     
00529     for(size_t i=0; i<3; ++i) {
00530       const GaussLobatto& gaussLobattoPoints = *gaussLobatto[i];
00531       for(size_t j=0; j<gaussLobattoPoints.numberOfPoints(); ++j){
00532         
00533         // Compute position of vertex j in direction i
00534         const real_t& xj = gaussLobattoPoints(j);
00535         
00536         legendreBaseValues[i][j].resize(legendreBasis[i]->dimension());
00537         legendreBasis[i]->getValues(xj,legendreBaseValues[i][j]);
00538         
00539         lagrangeBaseValues[i][j].resize(lagrangeBasis[i]->dimension());
00540         lagrangeBasis[i]->getValues(xj,lagrangeBaseValues[i][j]);
00541       }
00542     }
00543 
00544     Structured3DVector<real_t> u_ijk = legendre;
00545 
00549     for (size_t i=0; i < __legendreDimensions[0]; ++i) {
00550       const real_t wi_8 = 1./8 * (2*i+1);
00551       for (size_t j=0;j < __legendreDimensions[1]; ++j) { 
00552         const real_t wi_wj_8 = wi_8 * (2*j+1);
00553         for (size_t k=0; k < __legendreDimensions[2]; ++k) {
00554           const real_t wi_wj_wk_8 = wi_wj_8 * (2*k+1);
00555           u_ijk(i,j,k) *= wi_wj_wk_8 ;
00556         }
00557       }
00558     }
00559 
00560     
00561     Structured3DVector<real_t> u_ijt(Array3DShape(__legendreDimensions[0],
00562                                                   __legendreDimensions[1],
00563                                                   gaussLobatto[2]->numberOfPoints()));
00564     u_ijt = 0;
00565 
00566     {
00567       for (size_t i=0; i < __legendreDimensions[0]; ++i) {
00568         for (size_t j=0; j < __legendreDimensions[1]; ++j) {
00569           for (size_t k=0; k < __legendreDimensions[2]; ++k) {
00570             const real_t& u_ijk_value = u_ijk(i,j,k);
00571             for (size_t t=0; t< gaussLobatto[2]->numberOfPoints(); ++t) {
00572               u_ijt(i,j,t) += u_ijk_value * legendreBaseValues[2][t][k];
00573             }
00574           }
00575         }
00576       }
00577     }
00578     
00579     Structured3DVector<real_t> u_ist(Array3DShape(__legendreDimensions[0],
00580                                                    gaussLobatto[1]->numberOfPoints(),
00581                                                    gaussLobatto[2]->numberOfPoints()));
00582     u_ist = 0;
00583     
00584     {
00585       for (size_t i=0; i <__legendreDimensions[0]; ++i) {
00586         for (size_t j=0; j <__legendreDimensions[1]; ++j) {
00587           for (size_t t=0; t < gaussLobatto[2]->numberOfPoints(); ++t) {
00588             const real_t& u_ijt_value = u_ijt(i,j,t) ;
00589             for (size_t s=0; s < gaussLobatto[1]->numberOfPoints(); ++s) {
00590               u_ist(i,s,t) += u_ijt_value * legendreBaseValues[1][s][j];
00591             }
00592           }
00593         }
00594       }
00595     }
00596     
00597     Structured3DVector<real_t> u_rst(Array3DShape(gaussLobatto[0]->numberOfPoints(),
00598                                                   gaussLobatto[1]->numberOfPoints(),
00599                                                   gaussLobatto[2]->numberOfPoints()));
00600     u_rst = 0;
00601     {
00602       for (size_t i=0; i < __legendreDimensions[0]; ++i) {
00603         for (size_t s=0; s <gaussLobatto[1]->numberOfPoints(); ++s) {
00604           for (size_t t=0; t <gaussLobatto[2]->numberOfPoints(); ++t) {
00605             const real_t& u_ist_value = u_ist(i,s,t);
00606             for (size_t r=0; r<gaussLobatto[0]->numberOfPoints(); ++r) {
00607               u_rst(r,s,t) += u_ist_value * legendreBaseValues[0][r][i];
00608             }
00609           }
00610         }
00611       }
00612     }
00613 
00614     Structured3DVector<real_t> u_rst0(Array3DShape(gaussLobatto[0]->numberOfPoints(),
00615                                                    gaussLobatto[1]->numberOfPoints(),
00616                                                    __lagrangeDimensions[2]));
00617     u_rst0 = 0;
00618     
00619     {
00620       for (size_t r=0; r < gaussLobatto[0]->numberOfPoints(); ++r) {
00621         for (size_t s=0; s < gaussLobatto[1]->numberOfPoints(); ++s) {
00622           for (size_t t=0; t < gaussLobatto[2]->numberOfPoints(); ++t) {
00623             const real_t& wt = gaussLobatto[2]->weight(t);
00624             const real_t u_rst_value = u_rst(r,s,t) * wt;
00625             for (size_t t0=0; t0<__lagrangeDimensions[2]; ++t0) {
00626               u_rst0(r,s,t0) += u_rst_value * lagrangeBaseValues[2][t][t0];
00627             }
00628           }
00629         }
00630       }
00631     }
00632     
00633     Structured3DVector<real_t> u_rs0t0(Array3DShape(gaussLobatto[0]->numberOfPoints(),
00634                                                     __lagrangeDimensions[1],
00635                                                     __lagrangeDimensions[2]));
00636     u_rs0t0 = 0;
00637     
00638     {
00639       for (size_t r=0; r < gaussLobatto[0]->numberOfPoints(); ++r) {
00640         for (size_t s=0; s < gaussLobatto[1]->numberOfPoints(); ++s) {
00641           const real_t& ws = gaussLobatto[1]->weight(s);
00642           for (size_t t0=0; t0 < __lagrangeDimensions[2]; ++t0) {
00643             const real_t u_rst0_value = u_rst0(r,s,t0) * ws;
00644             for (size_t s0=0; s0<__lagrangeDimensions[1]; ++s0) {
00645               u_rs0t0(r,s0,t0) += u_rst0_value * lagrangeBaseValues[1][s][s0];
00646             }
00647           }
00648         }
00649       }
00650     }
00651     
00652     Structured3DVector<real_t>& u_r0s0t0 = lagrange;
00653     {
00654       for (size_t r=0; r < gaussLobatto[0]->numberOfPoints(); ++r) {
00655         const real_t& wr = gaussLobatto[0]->weight(r);
00656         for (size_t s0=0; s0 < __lagrangeDimensions[1]; ++s0) {
00657           for (size_t t0=0; t0 < __lagrangeDimensions[2]; ++t0) {
00658             const real_t u_rs0t0_value = u_rs0t0(r,s0,t0) * wr;
00659             for (size_t r0=0; r0<__lagrangeDimensions[0]; ++r0) {
00660               u_r0s0t0(r0,s0,t0) += u_rs0t0_value * lagrangeBaseValues[0][r][r0];
00661             }
00662           }
00663         }
00664       }
00665     }
00666   }

Here is the call graph for this function:

void SpectralFEMPreconditioner::Internal::__residuToLegendre ( const Structured3DVector< real_t > &  residu,
Structured3DVector< real_t > &  legendre 
) const [inline, private]

Definition at line 668 of file SpectralFEMPreconditioner.cpp.

References __legendreDimensions.

Referenced by computes(), and computesTransposed().

00670   {
00671     legendre = residu;
00672 
00673     for (size_t i=0; i < __legendreDimensions[0]; ++i) {
00674       const real_t wi_8 = 1./8 * (2*i+1);
00675       for (size_t j=0;j < __legendreDimensions[1]; ++j) { 
00676         const real_t wi_wj_8 = wi_8 * (2*j+1);
00677         for (size_t k=0; k < __legendreDimensions[2]; ++k) {
00678           const real_t wi_wj_wk_8 = wi_wj_8 * (2*k+1);
00679           legendre(i,j,k) *= wi_wj_wk_8 ;
00680         }
00681       }
00682     }
00683   }

void SpectralFEMPreconditioner::Internal::__legendreToResidu ( const Structured3DVector< real_t > &  legendre,
Structured3DVector< real_t > &  residu 
) const [inline, private]

Definition at line 685 of file SpectralFEMPreconditioner.cpp.

References __legendreDimensions.

Referenced by computes(), and computesTransposed().

00687   {
00688     residu = legendre;
00689 
00690     for (size_t i=0; i < __legendreDimensions[0]; ++i) {
00691       const real_t wi_8 = 1./8 * (2*i+1);
00692       for (size_t j=0;j < __legendreDimensions[1]; ++j) { 
00693         const real_t wi_wj_8 = wi_8 * (2*j+1);
00694         for (size_t k=0; k < __legendreDimensions[2]; ++k) {
00695           const real_t wi_wj_wk_8 = wi_wj_8 * (2*k+1);
00696           residu(i,j,k) /= wi_wj_wk_8 ;
00697         }
00698       }
00699     }
00700   }

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

Computes $ z = C^{-1}r $

Parameters:
r given residue
z preconditioned residue

Definition at line 720 of file SpectralFEMPreconditioner.cpp.

References __a, __b, __lagrangeDegrees, __lagrangeDimensions, __lagrangeToLegendre(), __lagrangeVertices, __legendreDegrees, __legendreDimensions, __legendreToLagrange(), __legendreToResidu(), __residuToLegendre(), ScalarDiscretizationTypeSpectral::a(), ScalarDiscretizationTypeSpectral::b(), ScalarDiscretizationTypeSpectral::degrees(), SolverInformationCenter::discretizationType(), fferr(), GaussLobattoManager::get(), StaticBase< GaussLobattoManager >::instance(), StaticBase< SolverInformationCenter >::instance(), SolverInformationCenter::mesh(), Structured3DMeshShape::numberOfVertices(), Vector< T >::size(), ScalarDiscretizationTypeBase::spectralLegendre, Mesh::spectralMesh, Mesh::type(), ScalarDiscretizationTypeBase::type(), ErrorHandler::unexpected, and GaussLobatto::vertices().

00722   {
00723     const Mesh& solverMesh = SolverInformationCenter::instance().mesh();
00724     const DiscretizationType& discretization = SolverInformationCenter::instance().discretizationType();
00725     
00726     // Only works for scalar
00727     const ScalarDiscretizationTypeBase& scalarDiscretization = discretization[0];
00728     if (scalarDiscretization.type() != ScalarDiscretizationTypeBase::spectralLegendre) {
00729       throw ErrorHandler(__FILE__,__LINE__,
00730                          "bad discretization",
00731                          ErrorHandler::unexpected);
00732     }
00733     
00734     const ScalarDiscretizationTypeSpectral& spectralDiscretization
00735       = dynamic_cast<const ScalarDiscretizationTypeSpectral&>(scalarDiscretization);
00736     
00737     __legendreDegrees = spectralDiscretization.degrees();
00738     __legendreDimensions = __legendreDegrees + TinyVector<3,size_t>(1,1,1);
00739     __a = spectralDiscretization.a();
00740     __b = spectralDiscretization.b();
00741 
00742     const bool useGaussLobatto = false;
00743     if(useGaussLobatto) {
00744       __lagrangeDegrees    = __legendreDegrees;
00745       __lagrangeDimensions = __legendreDimensions;
00746 
00747       for (size_t i=0; i<3; ++i) {
00748         __lagrangeVertices[i].resize(__legendreDimensions[i]);
00749       }
00750 
00751       for (size_t i=0; i<3; ++i) {
00752         const GaussLobatto& gaussLobatto = GaussLobattoManager::instance().get(__legendreDegrees[i]);
00753         __lagrangeVertices[i] = gaussLobatto.vertices();
00754       }
00755     } else {
00756       __lagrangeDegrees    = __legendreDegrees + TinyVector<3,size_t>(0,0,0);
00757       __lagrangeDimensions = __lagrangeDegrees + TinyVector<3,size_t>(1,1,1);
00758 
00759       for (size_t i=0; i<3; ++i) {
00760         __lagrangeVertices[i].resize(__lagrangeDimensions[i]);
00761       }
00762 
00763       for (size_t i=0; i<3; ++i) {
00764 
00765         const real_t h = std::abs(__b[i]-__a[i])/(__lagrangeDegrees[i]);
00766         Vector<real_t>& vertices = __lagrangeVertices[i];
00767         const real_t x0 = std::min(__a[i],__b[i]);
00768 
00769         for (size_t j=0; j<vertices.size(); ++j) {
00770           vertices[j] = x0 + j*h;
00771         }
00772       }
00773     }
00774 
00775 
00776     if (solverMesh.type() == Mesh::spectralMesh) {
00777       Structured3DVector<real_t> residu(__legendreDimensions);
00778       residu = r;
00779 //       std::cout << "----------------------\n";
00780 //       std::cout << "residu=\n" << residu;
00781 
00782       Structured3DVector<real_t> legendreResidu(__legendreDimensions);
00783 
00784       __residuToLegendre(residu,legendreResidu);
00785       //      legendreResidu = residu;
00786 //       std::cout << "----------------------\n";
00787 //       std::cout << "legendre=\n" << legendreResidu;
00788 
00789       Structured3DVector<real_t> lagrangeResidu(__lagrangeDimensions);
00790 
00791       __legendreToLagrange(legendreResidu, lagrangeResidu);
00792 
00793 //       std::cout << "----------------------\n";
00794 //       std::cout << "lagrange=\n" << lagrangeResidu;
00795 
00796       if (useGaussLobatto) {
00797         Structured3DMeshShape meshShape(__lagrangeDimensions-TinyVector<3,size_t>(2,2,2),
00798                                         __a,__b);
00799         ReferenceCounting<SpectralMesh> mesh
00800           = new SpectralMesh(meshShape,
00801                              new VerticesCorrespondance(__lagrangeDimensions[0]*__lagrangeDimensions[1]*__lagrangeDimensions[2]));
00802         __solveFEM<SpectralMesh>(mesh,lagrangeResidu);
00803       } else {
00804         Structured3DMeshShape meshShape(__lagrangeDimensions,
00805                                         __a,__b);
00806         ReferenceCounting<Structured3DMesh> mesh
00807           = new Structured3DMesh(meshShape,
00808                                  new VerticesCorrespondance(meshShape.numberOfVertices()));
00809         __solveFEM<Structured3DMesh>(mesh,lagrangeResidu);
00810       }
00811 
00812 //       std::cout << "----------------------\n";
00813 //       std::cout << "lagrange=\n" << lagrangeResidu << '\n';
00814 
00815       __lagrangeToLegendre(lagrangeResidu, legendreResidu);
00816 //       std::cout << "----------------------\n";
00817 //       std::cout << "legendre=\n" << legendreResidu << '\n';
00818       
00819       __legendreToResidu(legendreResidu,residu);
00820 
00821       z = residu;
00822 //       std::cout << "----------------------\n";
00823 //       std::cout << "residu=\n" << residu << '\n';
00824 //       //      std::exit(0);
00825 //       std::cout << "(z,r) 1 = " << r*z << '\n';
00826 //       std::cout << Norm(z-r)/Norm(r) << '\n';
00827     } else {
00828       fferr(0) << __FILE__ << ':' << __LINE__ << ": Not implemented\n";
00829       std::exit(1);
00830     }
00831 
00832   }

Here is the call graph for this function:

void SpectralFEMPreconditioner::Internal::computesTransposed ( const Vector< real_t > &  r,
Vector< real_t > &  z 
) const [inline]

Definition at line 834 of file SpectralFEMPreconditioner.cpp.

References __a, __b, __lagrangeDegrees, __lagrangeDimensions, __lagrangeToLegendreTransposed(), __lagrangeVertices, __legendreDegrees, __legendreDimensions, __legendreToLagrangeTransposed(), __legendreToResidu(), __residuToLegendre(), ScalarDiscretizationTypeSpectral::a(), ScalarDiscretizationTypeSpectral::b(), ScalarDiscretizationTypeSpectral::degrees(), SolverInformationCenter::discretizationType(), fferr(), GaussLobattoManager::get(), StaticBase< GaussLobattoManager >::instance(), StaticBase< SolverInformationCenter >::instance(), SolverInformationCenter::mesh(), Structured3DMeshShape::numberOfVertices(), Vector< T >::size(), ScalarDiscretizationTypeBase::spectralLegendre, Mesh::spectralMesh, Mesh::type(), ScalarDiscretizationTypeBase::type(), ErrorHandler::unexpected, and GaussLobatto::vertices().

00836   {
00837     const Mesh& solverMesh = SolverInformationCenter::instance().mesh();
00838     const DiscretizationType& discretization = SolverInformationCenter::instance().discretizationType();
00839     
00840     // Only works for scalar
00841     const ScalarDiscretizationTypeBase& scalarDiscretization = discretization[0];
00842     if (scalarDiscretization.type() != ScalarDiscretizationTypeBase::spectralLegendre) {
00843       throw ErrorHandler(__FILE__,__LINE__,
00844                          "bad discretization",
00845                          ErrorHandler::unexpected);
00846     }
00847     
00848     const ScalarDiscretizationTypeSpectral& spectralDiscretization
00849       = dynamic_cast<const ScalarDiscretizationTypeSpectral&>(scalarDiscretization);
00850     
00851     __legendreDegrees = spectralDiscretization.degrees();
00852     __legendreDimensions = __legendreDegrees + TinyVector<3,size_t>(1,1,1);
00853     __a = spectralDiscretization.a();
00854     __b = spectralDiscretization.b();
00855 
00856     const bool useGaussLobatto = false;
00857     if(useGaussLobatto) {
00858       __lagrangeDegrees    = __legendreDegrees;
00859       __lagrangeDimensions = __legendreDimensions;
00860 
00861       for (size_t i=0; i<3; ++i) {
00862         __lagrangeVertices[i].resize(__legendreDimensions[i]);
00863       }
00864 
00865       for (size_t i=0; i<3; ++i) {
00866         const GaussLobatto& gaussLobatto = GaussLobattoManager::instance().get(__legendreDegrees[i]);
00867         __lagrangeVertices[i] = gaussLobatto.vertices();
00868       }
00869     } else {
00870       __lagrangeDegrees    = __legendreDegrees + TinyVector<3,size_t>(0,0,0);
00871       __lagrangeDimensions = __lagrangeDegrees + TinyVector<3,size_t>(1,1,1);
00872 
00873       for (size_t i=0; i<3; ++i) {
00874         __lagrangeVertices[i].resize(__lagrangeDimensions[i]);
00875       }
00876 
00877       for (size_t i=0; i<3; ++i) {
00878 
00879         const real_t h = std::abs(__b[i]-__a[i])/(__lagrangeDegrees[i]);
00880         Vector<real_t>& vertices = __lagrangeVertices[i];
00881         const real_t x0 = std::min(__a[i],__b[i]);
00882 
00883         for (size_t j=0; j<vertices.size(); ++j) {
00884           vertices[j] = x0 + j*h;
00885         }
00886       }
00887     }
00888 
00889     if (solverMesh.type() == Mesh::spectralMesh) {
00890       Structured3DVector<real_t> residu(__legendreDimensions);
00891       residu = r;
00892 
00893       Structured3DVector<real_t> legendreResidu(__legendreDimensions);
00894       Structured3DVector<real_t> lagrangeResidu(__lagrangeDimensions);
00895 
00896       __legendreToResidu(residu,legendreResidu);
00897       __lagrangeToLegendreTransposed(legendreResidu,lagrangeResidu);
00898       Structured3DMeshShape meshShape(__lagrangeDimensions,
00899                                       __a,__b);
00900       ReferenceCounting<Structured3DMesh> mesh
00901         = new Structured3DMesh(meshShape,
00902                                new VerticesCorrespondance(meshShape.numberOfVertices()));
00903       __solveFEM<Structured3DMesh>(mesh,lagrangeResidu);
00904       __legendreToLagrangeTransposed(lagrangeResidu, legendreResidu);
00905       __residuToLegendre(legendreResidu,residu);
00906 
00907       z = residu;
00908 //       std::cout << "(z,r) 2 = " << r*z << '\n';
00909 //       std::cout << Norm(z-r)/Norm(r) << '\n';
00910     } else {
00911       fferr(0) << __FILE__ << ':' << __LINE__ << ": Not implemented\n";
00912       std::exit(1);
00913     }
00914 
00915   }

Here is the call graph for this function:


Member Data Documentation

Definition at line 63 of file SpectralFEMPreconditioner.cpp.

Referenced by __solveFEM().

Definition at line 71 of file SpectralFEMPreconditioner.cpp.

Referenced by computes(), and computesTransposed().

Definition at line 72 of file SpectralFEMPreconditioner.cpp.

Referenced by computes(), and computesTransposed().


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

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