
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 |
Definition at line 60 of file SpectralFEMPreconditioner.cpp.
| SpectralFEMPreconditioner::Internal::Internal | ( | const Problem & | problem | ) | [inline] |
Constructor
| problem | problem to precondition |
Definition at line 708 of file SpectralFEMPreconditioner.cpp.
00709 : __problem(problem) 00710 { 00711 ; 00712 }
| 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 }

| 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 }

| 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 }

| 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 }

| 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 }

| 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 
| 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 }

| 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 }

const Problem& SpectralFEMPreconditioner::Internal::__problem [private] |
TinyVector<3,size_t> SpectralFEMPreconditioner::Internal::__legendreDegrees [mutable, private] |
Definition at line 65 of file SpectralFEMPreconditioner.cpp.
Referenced by __lagrangeToLegendre(), __lagrangeToLegendreTransposed(), __legendreToLagrange(), __legendreToLagrangeTransposed(), computes(), and computesTransposed().
TinyVector<3,size_t> SpectralFEMPreconditioner::Internal::__legendreDimensions [mutable, private] |
Definition at line 66 of file SpectralFEMPreconditioner.cpp.
Referenced by __lagrangeToLegendre(), __lagrangeToLegendreTransposed(), __legendreToLagrange(), __legendreToLagrangeTransposed(), __legendreToResidu(), __residuToLegendre(), computes(), and computesTransposed().
TinyVector<3,size_t> SpectralFEMPreconditioner::Internal::__lagrangeDegrees [mutable, private] |
Definition at line 68 of file SpectralFEMPreconditioner.cpp.
Referenced by __lagrangeToLegendre(), __lagrangeToLegendreTransposed(), computes(), and computesTransposed().
TinyVector<3,size_t> SpectralFEMPreconditioner::Internal::__lagrangeDimensions [mutable, private] |
Definition at line 69 of file SpectralFEMPreconditioner.cpp.
Referenced by __lagrangeToLegendre(), __lagrangeToLegendreTransposed(), __legendreToLagrange(), __legendreToLagrangeTransposed(), computes(), and computesTransposed().
TinyVector<3,real_t> SpectralFEMPreconditioner::Internal::__a [mutable, private] |
Definition at line 71 of file SpectralFEMPreconditioner.cpp.
Referenced by computes(), and computesTransposed().
TinyVector<3,real_t> SpectralFEMPreconditioner::Internal::__b [mutable, private] |
Definition at line 72 of file SpectralFEMPreconditioner.cpp.
Referenced by computes(), and computesTransposed().
TinyVector<3,Vector<real_t> > SpectralFEMPreconditioner::Internal::__lagrangeVertices [mutable, private] |
Definition at line 74 of file SpectralFEMPreconditioner.cpp.
Referenced by __lagrangeToLegendre(), __lagrangeToLegendreTransposed(), __legendreToLagrange(), __legendreToLagrangeTransposed(), computes(), and computesTransposed().
1.5.6