00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <SpectralFEMPreconditioner.hpp>
00021
00022 #include <MultiGrid.hpp>
00023
00024 #include <Structured3DMesh.hpp>
00025 #include <SpectralMesh.hpp>
00026
00027 #include <DiscretizationType.hpp>
00028 #include <DegreeOfFreedomSetBuilder.hpp>
00029
00030 #include <MatrixManagement.hpp>
00031 #include <SolverInformationCenter.hpp>
00032
00033 #include <FEMDiscretization.hpp>
00034 #include <BoundaryConditionDiscretizationFEM.hpp>
00035
00036 #include <ScalarDiscretizationTypeSpectral.hpp>
00037
00038 #include <SpectralConformTransformation.hpp>
00039
00040 #include <LegendreBasis.hpp>
00041 #include <LagrangeBasis.hpp>
00042
00043 #include <IdentityPrecond.hpp>
00044 #include <DiagPrecond.hpp>
00045 #include <ConjugateGradient.hpp>
00046
00047 #include <FEMFunctionBuilder.hpp>
00048 #include <FEMFunction.hpp>
00049
00050 #include <VariationalProblem.hpp>
00051 #include <ScalarFunctionConstant.hpp>
00052 #include <VariationalOperatorAlphaUV.hpp>
00053 #include <VariationalOperatorFV.hpp>
00054
00055 #include <SpectralLegendreDiscretizationConform.hpp>
00056 #include <BoundaryConditionDiscretizationSpectralConform.hpp>
00057
00058 #include <SparseMatrix.hpp>
00059
00060 class SpectralFEMPreconditioner::Internal
00061 {
00062 private:
00063 const Problem& __problem;
00064
00065 mutable TinyVector<3,size_t> __legendreDegrees;
00066 mutable TinyVector<3,size_t> __legendreDimensions;
00067
00068 mutable TinyVector<3,size_t> __lagrangeDegrees;
00069 mutable TinyVector<3,size_t> __lagrangeDimensions;
00070
00071 mutable TinyVector<3,real_t> __a;
00072 mutable TinyVector<3,real_t> __b;
00073
00074 mutable TinyVector<3,Vector<real_t> > __lagrangeVertices;
00075
00076 template <typename MeshType>
00077 void __solveFEM(ConstReferenceCounting<MeshType> mesh,
00078 Structured3DVector<real_t>& lagrange) const
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
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
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;
00168
00169 t.stop();
00170 ffout(4) << "Matrix copy: " << t << '\n';
00171 }
00172
00173
00174
00175
00176
00177 Structured3DVector<real_t> residu(lagrange);
00178 MultiGrid M(__problem,static_cast<const SparseMatrix&>(*femA),degreeOfFreedomSet);
00179 M.computes(residu,lagrange);
00180
00181
00182
00183
00184
00185
00186
00187 }
00188
00189
00190 void __legendreToLagrange(const Structured3DVector<real_t>& legendre,
00191 Structured3DVector<real_t>& lagrange) const
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
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 }
00266
00267 void __legendreToLagrangeTransposed(const Structured3DVector<real_t>& lagrange,
00268 Structured3DVector<real_t>& legendre) const
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
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 }
00343
00344 void __lagrangeToLegendre(const Structured3DVector<real_t>& lagrange,
00345 Structured3DVector<real_t>& legendre) const
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
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
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 }
00504
00505 void __lagrangeToLegendreTransposed(const Structured3DVector<real_t>& legendre,
00506 Structured3DVector<real_t>& lagrange) const
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
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 }
00667
00668 void __residuToLegendre (const Structured3DVector<real_t>& residu,
00669 Structured3DVector<real_t>& legendre) const
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 }
00684
00685 void __legendreToResidu(const Structured3DVector<real_t>& legendre,
00686 Structured3DVector<real_t>& residu) const
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 }
00701
00702 public:
00708 Internal(const Problem& problem)
00709 : __problem(problem)
00710 {
00711 ;
00712 }
00713
00720 void computes(const Vector<real_t>& r,
00721 Vector<real_t>& z) const
00722 {
00723 const Mesh& solverMesh = SolverInformationCenter::instance().mesh();
00724 const DiscretizationType& discretization = SolverInformationCenter::instance().discretizationType();
00725
00726
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
00780
00781
00782 Structured3DVector<real_t> legendreResidu(__legendreDimensions);
00783
00784 __residuToLegendre(residu,legendreResidu);
00785
00786
00787
00788
00789 Structured3DVector<real_t> lagrangeResidu(__lagrangeDimensions);
00790
00791 __legendreToLagrange(legendreResidu, lagrangeResidu);
00792
00793
00794
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
00813
00814
00815 __lagrangeToLegendre(lagrangeResidu, legendreResidu);
00816
00817
00818
00819 __legendreToResidu(legendreResidu,residu);
00820
00821 z = residu;
00822
00823
00824
00825
00826
00827 } else {
00828 fferr(0) << __FILE__ << ':' << __LINE__ << ": Not implemented\n";
00829 std::exit(1);
00830 }
00831
00832 }
00833
00834 void computesTransposed(const Vector<real_t>& r,
00835 Vector<real_t>& z) const
00836 {
00837 const Mesh& solverMesh = SolverInformationCenter::instance().mesh();
00838 const DiscretizationType& discretization = SolverInformationCenter::instance().discretizationType();
00839
00840
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
00909
00910 } else {
00911 fferr(0) << __FILE__ << ':' << __LINE__ << ": Not implemented\n";
00912 std::exit(1);
00913 }
00914
00915 }
00916 };
00917
00918 void SpectralFEMPreconditioner::
00919 initializes()
00920 {
00921 int oldVerbosity = StreamCenter::instance().getDebugLevel();
00922 StreamCenter::instance().setDebugLevel(oldVerbosity-5);
00923 __internal = new SpectralFEMPreconditioner::Internal(__problem);
00924 StreamCenter::instance().setDebugLevel(oldVerbosity);
00925 }
00926
00927 void
00928 SpectralFEMPreconditioner::
00929 computes(const Vector<real_t>& r,
00930 Vector<real_t>& z) const
00931 {
00932 int oldVerbosity = StreamCenter::instance().getDebugLevel();
00933 StreamCenter::instance().setDebugLevel(oldVerbosity-5);
00934 __internal->computes(r,z);
00935 StreamCenter::instance().setDebugLevel(oldVerbosity);
00936 }
00937
00938 void
00939 SpectralFEMPreconditioner::
00940 computesTransposed(const Vector<real_t>& r,
00941 Vector<real_t>& z) const
00942 {
00943 int oldVerbosity = StreamCenter::instance().getDebugLevel();
00944 StreamCenter::instance().setDebugLevel(oldVerbosity-5);
00945 __internal->computesTransposed(r,z);
00946 StreamCenter::instance().setDebugLevel(oldVerbosity);
00947 }
00948
00949 SpectralFEMPreconditioner::
00950 SpectralFEMPreconditioner(const Problem& problem)
00951 : Preconditioner (problem,
00952 Preconditioner::spectralFEM)
00953 {
00954 ;
00955 }
00956
00957 SpectralFEMPreconditioner::
00958 ~SpectralFEMPreconditioner()
00959 {
00960 ;
00961 }