00001
00002
00003
00004
00005 #ifndef _Operators_
00006 # define _Operators_
00007 # include <math.h>
00008
00009 #include "AdaptiveData.hpp"
00010 #include "UniformData.hpp"
00011 #include "LevelAdaptive.hpp"
00012
00013
00014
00015 extern int debugRefine ;
00016
00018 template<class I , int DIM>
00019 struct Operator {
00021 virtual void Apply (I *X , I *Result)=0 ;
00023 virtual void Preconditioner (I *X , I *Result)=0 ;
00025 virtual void InversePreconditioner(I *X , I *Result)=0 ;
00027 virtual double DiagonalEntry (int *level , Wavelets *W)=0 ;
00030 virtual void NotUsing (I *X)=0 ;
00031 } ;
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 template<int DIM>
00048 void HelmholtzDiagonalPreconditioner(AdaptiveData<DIM> *X , AdaptiveData<DIM> *R, Operator<AdaptiveData<DIM>,DIM> *O , bool inverse) ;
00049
00050 template<int DIM>
00051 void HelmholtzDiagonalPreconditioner(UniformData<DIM> *X , UniformData<DIM> *R, Operator<UniformData<DIM>,DIM> *O , bool inverse) ;
00052
00053 template<class I , int DIM>
00054 void InverseHelmholtzDiagonalPreconditioner(I *X , I *Result , Operator<AdaptiveData<DIM>,DIM> *O) ;
00055
00057
00058
00059
00060
00061
00062
00063 template<class I , int DIM>
00064 struct HelmholtzOperator : public Operator<I,DIM> {
00065
00067 HelmholtzOperator() ;
00069 virtual void Apply (I *X , I *Result) ;
00071 virtual void Preconditioner(I *X , I *Result) ;
00073 virtual void InversePreconditioner(I *X , I *Result) ;
00075 virtual double DiagonalEntry (int *level , Wavelets *W) ;
00076 virtual void NotUsing (I *X) ;
00077
00079 double par[DIM+1] ;
00080
00081 I *Null ;
00082
00084 I *Tmp ;
00086 I *Tmp2 ;
00087
00088 bool use_lifting_preconditioner ;
00089
00090 } ;
00091
00092 template<class I , int DIM>
00093 struct SpaceTimeOperator : public Operator<I,DIM> {
00094
00096 SpaceTimeOperator() ;
00098 virtual void Apply (I *X , I *Result) ;
00100 virtual void Preconditioner(I *X , I *Result) ;
00102 virtual void InversePreconditioner(I *X , I *Result) ;
00104 virtual double DiagonalEntry (int *level , Wavelets *W) ;
00105 virtual void NotUsing (I *X) ;
00106
00107 void DiagonalScale (I *X , bool inverse) ;
00109 I *Tmp, *Tmp2 ;
00110
00112 bool use_lifting_preconditioner ;
00113 } ;
00114
00115
00116
00122 template<class I , int DIM>
00123 struct IntegroDifferentialOperator : public Operator<I , DIM> {
00125 double par[3] ;
00127 Operator<I , DIM> *D ;
00129 LevelAdaptiveData<2*DIM> *K ;
00131 I *Tmp ;
00132
00134 IntegroDifferentialOperator() ;
00136 virtual void Apply (I *X , I *Result) ;
00138 virtual void Preconditioner(I *X , I *Result) ;
00140 virtual void InversePreconditioner(I *X , I *Result ) ;
00142 virtual double DiagonalEntry (int *level , Wavelets *W) ;
00143 virtual void NotUsing (I *X) ;
00144 } ;
00145
00146
00147
00148
00149
00150
00151
00152 template<class I , int DIM>
00153 struct TensorIntegroDifferentialOperator : public Operator<I , DIM> {
00154 double par[3] ;
00155 Operator<I , DIM> * D ;
00156 LevelAdaptiveData<DIM> *KX,*KY ;
00157 I *Tmp ;
00158
00159 TensorIntegroDifferentialOperator() ;
00160 virtual void Apply (I *X , I *Result) ;
00161 virtual void Preconditioner(I *X , I *Result) ;
00162 virtual void InversePreconditioner(I *X , I *Result ) ;
00163 virtual double DiagonalEntry (int *level , Wavelets *W) ;
00164 virtual void NotUsing (I *X) ;
00165 } ;
00166
00167
00169 template<class I , int DIM>
00170 struct PressureOperatorI : public Operator<I,DIM> {
00171 I *Tmp[2] ;
00172 I *Null ;
00173 bool do_patch ;
00174 bool use_lifting_preconditioner ;
00175
00176 PressureOperatorI() ;
00177 virtual void Apply (I *X , I *Result) ;
00178 virtual void Preconditioner(I *X , I *Result) ;
00179 virtual void InversePreconditioner(I *X , I *Result) ;
00180 virtual double DiagonalEntry (int *level , Wavelets *W) ;
00181 virtual void NotUsing (I *X) ;
00182 } ;
00183
00184
00193
00194
00195
00196
00197
00198
00199
00200
00201 template<class I , int DIM>
00202 struct PressureOperatorII : public Operator<I,DIM> {
00203 I *Tmp[2] ;
00204 I *Null ;
00205 bool do_restrict ;
00206 bool do_patch ;
00207 bool use_lifting_preconditioner ;
00208
00209 PressureOperatorII() ;
00210 virtual void Apply (I *X , I *Result) ;
00211 virtual void Preconditioner(I *X , I *Result) ;
00212 virtual void InversePreconditioner(I *X , I *Result) ;
00213 virtual double DiagonalEntry (int *level , Wavelets *W) ;
00214 virtual void NotUsing (I *X) ;
00215 } ;
00216
00218 template<class I , int DIM>
00219 struct PressureOperatorIII : public Operator<I,DIM> {
00220 I *Tmp[2] ;
00221 I *Null ;
00222 bool do_restrict ;
00223 bool do_patch ;
00224 bool use_lifting_preconditioner ;
00225
00226 PressureOperatorIII() ;
00227 virtual void Apply (I *X , I *Result) ;
00228 virtual void Preconditioner(I *X , I *Result) ;
00229 virtual void InversePreconditioner(I *X , I *Result) ;
00230 virtual double DiagonalEntry (int *level , Wavelets *W) ;
00231 virtual void NotUsing (I *X) ;
00232 } ;
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 template<class I , int DIM>
00246 struct PressureOperatorIV : public Operator<I,DIM> {
00247 I *Tmp[2] ;
00248 I *Null ;
00249 bool do_restrict ;
00250 bool do_patch ;
00251 bool use_lifting_preconditioner ;
00252
00253 PressureOperatorIV() ;
00254 virtual void Apply (I *X , I *Result) ;
00255 virtual void Preconditioner(I *X , I *Result) ;
00256 virtual void InversePreconditioner(I *X , I *Result) ;
00257 virtual double DiagonalEntry (int *level , Wavelets *W) ;
00258 virtual void NotUsing (I *X) ;
00259 } ;
00260
00261
00262 template<class I , int DIM>
00263 struct PressureOperatorV : public Operator<I,DIM> {
00264 I *Tmp ;
00265 I *Null ;
00266 bool do_restrict ;
00267 bool do_patch ;
00268 bool use_lifting_preconditioner ;
00269
00270 PressureOperatorV() ;
00271 virtual void Apply (I *X , I *Result) ;
00272 virtual void Applyi (I *X , I *Result,int i) ;
00273 virtual void Preconditioner(I *X , I *Result) ;
00274 virtual void InversePreconditioner(I *X , I *Result) ;
00275 virtual double DiagonalEntry (int *level , Wavelets *W) ;
00276 virtual void NotUsing (I *X) ;
00277 } ;
00278
00279
00280
00281
00282
00283
00284
00287
00288 struct ConvectionOperator : public Operator<I,DIM> {
00289
00291 ConvectionOperator() ;
00293 void ApplyConservativeWENO(I *X , I *Result) ;
00294 void ApplyConservativeWENOUniformData(UniformData<DIM> *X , UniformData<DIM> *Result, bool trafo=false) ;
00296 virtual void Apply (I *X , I *Result) ;
00298 void ApplyFD (I *X , I *Result) ;
00300 void ApplyConservative (I *X , I *Result) ;
00302 void ApplyConservativeFD (I *X , I *Result) ;
00303 void ApplyConservativeFast(int i , I *Result) ;
00304
00305 virtual void Preconditioner (I *X , I *Result) ;
00306 virtual void InversePreconditioner(I *X , I *Result) ;
00307 virtual double DiagonalEntry (int *level , Wavelets *W) ;
00308 virtual void NotUsing (I *X) ;
00309
00311 I *U[DIM] ;
00313 I *Tmp,*Tmp1 ;
00314 } ;
00315
00316
00318
00319
00320
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 template<class I,int DIM>
00333 void Helmholtz(I *X , double *par, I *R, I *tmp, I *tmp2)
00334 {
00335 assert(tmp) ;
00336 assert(tmp!=R) ;
00337 assert(tmp!=X) ;
00338
00339 int i,last,op=STIFFNESS ;
00340 int BG[DIM][2] ;
00341 bool change=false ;
00342 bool lift[DIM] ;
00343 I *tmp3 =X ;
00344
00345 last=-1 ;
00346 for (i=0; i<=DIM; i++) if (par[i]!=0.0) last=i ;
00347
00348 if (last <0) {
00349 R->Set(0.0) ;
00350 R->SetBoundaryConditions(X) ;
00351 return ;
00352 }
00353 if (last==0) {
00354 R->Mul(X,par[0]) ;
00355 R->SetBoundaryConditions(X) ;
00356 return ;
00357 }
00358
00359
00360 for (i=0;i<DIM; i++) {
00361 if (X->Ext.islifting[i]) {
00362 assert(tmp2) ;
00363 tmp2->ApplyOp(X->Ext.BC[i], tmp3, i , LIFTING2INTERPOLET) ;
00364 tmp3 =tmp2 ;
00365 lift[i]=true ;
00366 } else
00367 lift[i]=false ;
00368 }
00369
00370
00371
00372
00373
00374 if ( X->Ext.WC->InterpoletFlag && (X->Ext.WC->N<=4) ) {
00375
00376 op = (X->Ext.WC->N == 2) ? FD22 : FD24II ;
00377 assert(tmp2!=tmp) ;
00378 assert(tmp2!=R) ;
00379 assert(tmp2!=X) ;
00380
00381 for (i=0;i<DIM; i++) {
00382 GetGeneralBoundaryConditions(X->Ext.BC[i],BG[i]) ;
00383 if ((X->Ext.BC[i][0]!=BG[i][0]) || (X->Ext.BC[i][1]!=BG[i][1])) change=true ;
00384 }
00385 if (change) {
00386 assert(tmp2) ;
00387 for (i=0;i<DIM; i++)
00388 tmp2->ApplyOp(BG[i], (i==0) ? tmp3 : tmp2 , i , PROJECTION) ;
00389 } else tmp2=tmp3 ;
00390 } else tmp2=tmp3 ;
00391
00392 R ->SetBoundaryConditions(tmp2->Ext.BC) ;
00393 tmp->SetBoundaryConditions(tmp2->Ext.BC) ;
00394
00395
00396
00397
00398
00399
00400
00401 tmp->Add(0.0, tmp2 , par[0],tmp2) ;
00402
00403 for (i=1;i<=DIM;i++)
00404 if (par[i]!=0.0) {
00405 R->ApplyOp(R->Ext.BC[i-1] , tmp2, i-1, op ) ;
00406
00407 if (i==last) R->Add (1.0, tmp , par[i],R) ;
00408 else tmp->PPlus( par[i],R) ;
00409 }
00410
00411 if (change)
00412 for (i=0; i<DIM; i++) R->ApplyOp(X->Ext.BC[i], R , i , PROJECTION) ;
00413
00414
00415 for (i=0; i<DIM; i++)
00416 if (lift[i]) R->ApplyOp(R->Ext.BC[i], R , i , INTERPOLET2LIFTING) ;
00417
00418 }
00419
00420
00421
00422
00423 template<int DIM>
00424 void HelmholtzDiagonalPreconditioner(AdaptiveData<DIM> *X , AdaptiveData<DIM> *R, Operator<AdaptiveData<DIM>,DIM> *O , bool inverse) {
00425 AdaptiveDataArray<DIM>::VectorArray::iterator it(&X->ba->d),dend=X->ba->d.end() ;
00426 AdaptiveDataArray<DIM>::DataVector *vx,*vr ;
00427 size_t i,n ;
00428 double diag ;
00429
00430 X->CheckAdaptiveGrid(R) ;
00431 assert(X->SameBoundaryConditions(R)) ;
00432
00433
00434
00435 for (it=X->ba->d.begin(); it<=dend; ++it) {
00436 vx=X->ba->d[it] ; vr=R->ba->d[it] ; n=(*vx).size() ;
00437
00438
00439 diag=O->DiagonalEntry( it.i , X->G->WC) ;
00440
00441 if (inverse) diag=1/diag ;
00442
00443
00444 for (i=0; i<n; i++) (*vr)[i] = (*vx)[i]/diag ;
00445 }
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 }
00487
00488
00489
00490
00491
00492 template<int DIM>
00493 void HelmholtzDiagonalPreconditioner(UniformData<DIM> *X , UniformData<DIM> *R, Operator<UniformData<DIM>,DIM> *O , bool inverse)
00494 {
00495 int Level0[DIM],J[DIM],i,a[DIM],e[DIM] ;
00496 double diag ;
00497
00498 X->ba->SameSize(R->ba) ;
00499
00500 X->ba->CalcLevel(J) ;
00501 for (i=0;i<DIM;i++) Level0[i]=X->Ext.WC->Level0 ;
00502
00503 Matrix<int,DIM>::iterator il(Level0 , J) ;
00504
00505 for (il.Set(Level0); il<=J; ++il) {
00506 for (i=0;i<DIM;i++) {
00507 if (il.i[i]==Level0[i]) a[i]=0 ;
00508 else a[i]=(1<<(il.i[i]-1))+1 ;
00509 e[i]=1<<il.i[i] ;
00510 }
00511
00512 Matrix<double,DIM>::iterator it(a,e) ;
00513
00514 diag=O->DiagonalEntry(il.i , X->Ext.WC) ;
00515 if (inverse) diag=1/diag ;
00516
00517 for (it.Set(a); it<=e; ++it) (*R->ba)[it] = (*X->ba)[it]/diag ;
00518 }
00519 }
00520
00521
00522
00523
00524 template<int DIM>
00525 void HelmholtzDiagonalPreconditioner(LevelAdaptiveData<DIM> *X , LevelAdaptiveData<DIM> *R, Operator<LevelAdaptiveData<DIM>,DIM> *O , bool inverse) {
00526 Matrix< Matrix<double,DIM>* , DIM>::iterator l(X->Level0,X->J) ;
00527 for (l.Set(X->Level0); l<=(*X->a).end(); ++l)
00528 if ((*X->A->a)[l.i]) {
00529 double diag=O->DiagonalEntry(l.i , X->Ext.WC) ;
00530 if (inverse) diag=1/diag ;
00531
00532 Matrix<double,DIM>::iterator t((*X->a)[l]),e=(*(*X->a)[l]).end() ;
00533 Matrix<double,DIM>* al=(*X->a)[l] ;
00534 Matrix<double,DIM>* bl=(*R->a)[l] ;
00535
00536 for (t=(*(*X->a)[l]).begin(); t<=e; ++t) (*bl)[t] = (*al)[t]/diag ;
00537 }
00538 }
00539
00540
00541
00542 template<class I , int DIM>
00543 void InverseHelmholtzDiagonalPreconditioner(I *X , I *Result , Operator<AdaptiveData<DIM>,DIM> *O) {
00544 HelmholtzDiagonalPreconditioner<DIM>(X,Result,O,true) ;
00545 }
00546
00547 template<class I , int DIM>
00548 void InverseHelmholtzDiagonalPreconditioner(I *X , I *Result , Operator<UniformData<DIM>,DIM> *O) {
00549 HelmholtzDiagonalPreconditioner<DIM>(X,Result,O,true) ;
00550 }
00551
00552 template<class I , int DIM>
00553 void InverseHelmholtzDiagonalPreconditioner(I *X , I *Result , Operator<LevelAdaptiveData<DIM>,DIM> *O) {
00554 HelmholtzDiagonalPreconditioner<DIM>(X,Result,O,true) ;
00555 }
00556
00557
00558
00559
00560
00561 template<class I , int DIM>
00562 HelmholtzOperator<I,DIM>::HelmholtzOperator() {
00563 Tmp=Tmp2=Null=NULL ;
00564 use_lifting_preconditioner=false ;
00565 }
00566
00567 template<class I , int DIM>
00568 void HelmholtzOperator<I,DIM>::NotUsing(I *X) { assert ((Tmp!=X)&&(Tmp2!=X)) ;}
00569
00570
00571 template<class I , int DIM>
00572 void HelmholtzOperator<I,DIM>::Apply(I *X , I *R) {
00573 NotUsing(X) ;
00574 NotUsing(R) ;
00575
00576 assert(Tmp) ;
00577
00578 Tmp->Ext.dimext=R->Ext.dimext=X->Ext.dimext ;
00579 if (Tmp2) Tmp2->Ext.dimext=X->Ext.dimext ;
00580
00581 Helmholtz<I,DIM>(X,par,R,Tmp,Tmp2 ) ;
00582
00583 if (X->Ext.dimext >0 ) {
00584 assert(Null) ;
00585 assert(X->Ext.dimext==1) ;
00586 R->PPlus(X->Ext.ext[0] , Null) ;
00587 R->Ext.ext[0]=Null->InnerProd(X) ;
00588 Tmp->Ext.dimext=Tmp2->Ext.dimext=0 ;
00589 } else {
00590
00591 }
00592
00593 }
00594
00595
00596 template<class I , int DIM>
00597 double HelmholtzOperator<I,DIM>::DiagonalEntry(int *l , Wavelets *W) {
00598 int i ;
00599 double d=par[0] ;
00600 if (W->InterpoletFlag) for (i=0;i<DIM;i++) d -= par[i+1]*pow(4.0,l[i]) ;
00601 else for (i=0;i<DIM;i++) d += par[i+1]*pow(4.0,l[i]) ;
00602 return d;
00603 }
00604
00605
00606 template<class I , int DIM>
00607 void HelmholtzOperator<I,DIM>::Preconditioner(I *X , I *R) {
00608 HelmholtzDiagonalPreconditioner<DIM>(X,R,this,false) ;
00609 R->Ext.CopyData(&X->Ext) ;
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 }
00625
00626 template<class I , int DIM>
00627 void HelmholtzOperator<I,DIM>::InversePreconditioner(I *X , I *R) {
00628 InverseHelmholtzDiagonalPreconditioner<I,DIM>(X,R,this) ;
00629 R->Ext.CopyData(&X->Ext) ;
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 }
00645
00646
00647
00648
00649 template<class I ,int DIM>
00650 IntegroDifferentialOperator<I,DIM>::IntegroDifferentialOperator() {
00651 par[0]=par[1]=par[2]=0 ;
00652 D=NULL ;
00653 K=NULL ;
00654 Tmp=NULL ;
00655 }
00656
00657 template<class I ,int DIM>
00658 void IntegroDifferentialOperator<I,DIM>::Apply(I *X , I *R) {
00659 assert(K) ;
00660
00661 if (par[2]==0) R->Set(0.0);
00662 else R->Multiply(K , X) ;
00663
00664 R->Add(par[0],X , par[2],R) ;
00665
00666 if (D) {
00667 NotUsing(X) ;
00668 NotUsing(R) ;
00669 D->NotUsing(X) ;
00670 D->NotUsing(R) ;
00671 D->NotUsing(Tmp) ;
00672
00673 D->Apply(X,Tmp) ;
00674 R->Add(1.0,R , par[1],Tmp) ;
00675 }
00676 }
00677
00678 template<class I , int DIM>
00679 void IntegroDifferentialOperator<I,DIM>::NotUsing(I *X) { assert (Tmp!=X) ;}
00680
00681 template<class I , int DIM>
00682 double IntegroDifferentialOperator<I,DIM>::DiagonalEntry(int *l , Wavelets *W) {
00683 int i ;
00684 double d=par[0] ;
00685 if (D) {
00686 if (W->InterpoletFlag) for (i=0;i<DIM;i++) d -= par[1]*pow(4.0,l[i]) ;
00687 else for (i=0;i<DIM;i++) d += par[1]*pow(4.0,l[i]) ;
00688 }
00689
00690 return d;
00691 }
00692
00693 template<class I , int DIM>
00694 void IntegroDifferentialOperator<I,DIM>::Preconditioner(I *X , I *R) {
00695 HelmholtzDiagonalPreconditioner<DIM>(X,R,this,false) ;
00696 }
00697
00698 template<class I , int DIM>
00699 void IntegroDifferentialOperator<I,DIM>::InversePreconditioner(I *X , I *R) {
00700 InverseHelmholtzDiagonalPreconditioner<I,DIM>(X,R,this) ;
00701 }
00702
00703
00704
00705
00706
00707 template<class I ,int DIM>
00708 TensorIntegroDifferentialOperator<I,DIM>::TensorIntegroDifferentialOperator() {
00709 par[0]=par[1]=par[2]=0 ;
00710 D=NULL ;
00711 KX=KY=NULL ;
00712 Tmp=NULL ;
00713 }
00714
00715 template<class I ,int DIM>
00716 void TensorIntegroDifferentialOperator<I,DIM>::Apply(I *X , I *R) {
00717 assert(KX) ;
00718 assert(KY) ;
00719
00720 double q=KY->InnerProd(X) ;
00721
00722 R->Add(par[0],X , par[2]*q,KX) ;
00723
00724 if (D) {
00725 NotUsing(X) ;
00726 NotUsing(R) ;
00727 D->NotUsing(X) ;
00728 D->NotUsing(R) ;
00729 D->NotUsing(Tmp) ;
00730
00731 D->Apply(X,Tmp) ;
00732 R->Add(1.0,R , par[1],Tmp) ;
00733 }
00734 }
00735
00736 template<class I , int DIM>
00737 void TensorIntegroDifferentialOperator<I,DIM>::NotUsing(I *X) { assert (Tmp!=X) ;}
00738
00739 template<class I , int DIM>
00740 double TensorIntegroDifferentialOperator<I,DIM>::DiagonalEntry(int *l , Wavelets *W) {
00741 int i ;
00742 double d=par[0] ;
00743 if (D) {
00744 if (W->InterpoletFlag) for (i=0;i<DIM;i++) d -= par[1]*pow(4.0,l[i]) ;
00745 else for (i=0;i<DIM;i++) d += par[1]*pow(4.0,l[i]) ;
00746 }
00747 return d;
00748 }
00749
00750 template<class I , int DIM>
00751 void TensorIntegroDifferentialOperator<I,DIM>::Preconditioner(I *X , I *R) {
00752 HelmholtzDiagonalPreconditioner<DIM>(X,R,this,false) ;
00753 }
00754
00755 template<class I , int DIM>
00756 void TensorIntegroDifferentialOperator<I,DIM>::InversePreconditioner(I *X , I *R) {
00757 InverseHelmholtzDiagonalPreconditioner<I,DIM>(X,R,this) ;
00758 }
00759
00760
00761
00762
00763
00764 template<class I,int DIM>
00765 PressureOperatorI<I,DIM>::PressureOperatorI() {
00766 Null=Tmp[0]=Tmp[1]=NULL ;
00767 do_patch=use_lifting_preconditioner=false ;
00768
00769 }
00770
00771 template<class I,int DIM>
00772 void PressureOperatorI<I,DIM>::NotUsing(I *X) { assert ((Tmp[0]!=X)&&(Tmp[1]!=X)&&(Null!=X)) ;}
00773
00774 template<class I,int DIM>
00775 double PressureOperatorI<I,DIM>::DiagonalEntry(int *l , Wavelets *) {
00776 int i ;
00777 double d=0.0 ;
00778 for (i=0;i<DIM;i++) {
00779 double dx=(G->XE[i] - G->XA[i]) ;
00780 d +=1./(dx*dx)*pow(4.0 , l[i] ) ;
00781 }
00782 return d;
00783 }
00784
00785 template<class I,int DIM>
00786 void PressureOperatorI<I,DIM>::Preconditioner(I *X , I *R) {
00787 int i ;
00788 I *Y=X ;
00789
00790 if (use_lifting_preconditioner) { for (i=0; i<DIM; i++) R->ApplyOp( (i==0) ? X : R , i , INTERPOLET2LIFTING) ; Y=R ; }
00791
00792 HelmholtzDiagonalPreconditioner(Y,R,this,false) ;
00793
00794 if (use_lifting_preconditioner) for (i=0; i<DIM; i++) R->ApplyOp( R , i , LIFTING2INTERPOLET) ;
00795
00796 R->Ext.CopyData(&X->Ext) ;
00797 }
00798
00799 template<class I,int DIM>
00800 void PressureOperatorI<I,DIM>::InversePreconditioner(I *X , I *R) {
00801 int i ;
00802 I *Y=X ;
00803
00804 if (use_lifting_preconditioner) { for (i=0; i<DIM; i++) R->ApplyOp( (i==0) ? X : R , i , INTERPOLET2LIFTING) ; Y=R ; }
00805
00806 InverseHelmholtzDiagonalPreconditioner(Y,R,this) ;
00807
00808 if (use_lifting_preconditioner) for (i=0; i<DIM; i++) R->ApplyOp( R , i , LIFTING2INTERPOLET) ;
00809
00810 R->Ext.CopyData(&X->Ext) ;
00811 }
00812
00813 template<class I,int DIM>
00814 void PressureOperatorI<I,DIM>::Apply(I *X , I *R) {
00815 NotUsing(X) ;
00816 NotUsing(R) ;
00817
00818 int i ;
00819 int BG[DIM][2] ;
00820 int op = ( X->G->WC->InterpoletFlag && (X->G->WC->N<=4) ) ? FD24 : STIFFNESS ;
00821
00822
00823 R->SetBoundaryConditions(X->Ext.BC) ;
00824 for (i=0; i<DIM; i++) {
00825 GetGeneralBoundaryConditions(X->Ext.BC[i] , BG[i]) ;
00826 if ((X->Ext.BC[i][0]==0) || (X->Ext.BC[i][1]==0)) assert(!X->extended) ;
00827 }
00828 Tmp[0]->Ext.dimext=Tmp[1]->Ext.dimext=X->Ext.dimext ;
00829
00830
00831 for (i=0; i<DIM; i++) Tmp[0]->ApplyOp(BG[i] , (i==0) ? X : Tmp[0] , i , PROJECTION) ;
00832
00833
00834 for (i=0; i<DIM; i++) {
00835 if (i==0) {
00836 R->ApplyOp(BG[i] , Tmp[0] , i , op) ;
00837
00838 }
00839 else {
00840 Tmp[1]->ApplyOp(BG[i] , Tmp[0] , i , op) ;
00841 R->PPlus(1 , Tmp[1]) ;
00842 }
00843 }
00844
00845 for (i=0; i<DIM; i++) R->ApplyOp(X->BC[i] , R , i , PROJECTION) ;
00846
00847 if (X->Ext.dimext>0) {
00848 assert(Null) ;
00849 assert(X->Ext.dimext==1) ;
00850 R->Ext.dimext=1 ;
00851 R->PPlus(X->Ext.ext[0],Null) ;
00852 R->Ext.ext[0]=Null->InnerProd(X) ;
00853 Tmp[0]->Ext.dimext=Tmp[1]->Ext.dimext=0 ;
00854 }
00855 }
00856
00857
00858
00859
00860
00861 template<class I,int DIM>
00862 PressureOperatorII<I,DIM>::PressureOperatorII() {
00863 Null=Tmp[0]=Tmp[1]=NULL ;
00864 do_patch=use_lifting_preconditioner=false ;
00865
00866 }
00867
00868 template<class I,int DIM>
00869 void PressureOperatorII<I,DIM>::NotUsing(I *X) { assert ((Tmp[0]!=X)&&(Tmp[1]!=X)&&(Null!=X)) ;}
00870
00871 template<class I,int DIM>
00872 double PressureOperatorII<I,DIM>::DiagonalEntry(int *l , Wavelets *) {
00873 int i ;
00874 double d=0.0 ;
00875 for (i=0;i<DIM;i++) d +=pow(4.0 , l[i]) ;
00876 return d;
00877 }
00878
00879 template<class I,int DIM>
00880 void PressureOperatorII<I,DIM>::Preconditioner(I *X , I *R) {
00881 int i ;
00882 I *Y=X ;
00883
00884 if (use_lifting_preconditioner) { for (i=0; i<DIM; i++) R->ApplyOp( (i==0) ? X : R , i , INTERPOLET2LIFTING) ; Y=R ; }
00885
00886 HelmholtzDiagonalPreconditioner(Y,R,this,false) ;
00887
00888 if (use_lifting_preconditioner) for (i=0; i<DIM; i++) R->ApplyOp( R , i , LIFTING2INTERPOLET) ;
00889
00890 if (X->extended) R->ext=X->ext ;
00891 }
00892
00893 template<class I,int DIM>
00894 void PressureOperatorII<I,DIM>::InversePreconditioner(I *X , I *R) {
00895 int i ;
00896 I *Y=X ;
00897
00898 if (use_lifting_preconditioner) { for (i=0; i<DIM; i++) R->ApplyOp( (i==0) ? X : R , i , INTERPOLET2LIFTING) ; Y=R ; }
00899
00900 InverseHelmholtzDiagonalPreconditioner(Y,R,this) ;
00901
00902 if (use_lifting_preconditioner) for (i=0; i<DIM; i++) R->ApplyOp( R , i , LIFTING2INTERPOLET) ;
00903
00904 if (X->extended) R->ext=X->ext ;
00905 }
00906
00907
00908
00909
00910
00911
00912 template<class I,int DIM>
00913 void PressureOperatorII<I,DIM>::Apply(I *X , I *R) {
00914 NotUsing(X) ;
00915 NotUsing(R) ;
00916
00917 int i ;
00918 int BG[DIM][2] ;
00919 int op = ( X->WC->InterpoletFlag && (X->WC->N<=2) ) ? DIVGRADFD4NOSTAB : DIVGRADNOSTAB ;
00920
00921
00922 R->SetBoundaryConditions(X->BC) ;
00923 for (i=0; i<DIM; i++) {
00924 GetGeneralBoundaryConditions(X->BC[i] , BG[i]) ;
00925 if ((X->BC[i][0]==0) || (X->BC[i][1]==0)) assert(!X->extended) ;
00926 }
00927 Tmp[0]->extended=Tmp[1]->extended=X->extended ;
00928
00929
00930 for (i=0; i<DIM; i++) Tmp[0]->ApplyOp(BG[i] , (i==0) ? X : Tmp[0] , i , PROJECTION) ;
00931
00932
00933 for (i=0; i<DIM; i++) {
00934 if (i==0) {
00935 R->ApplyOp(BG[i] , Tmp[0] , i , op) ;
00936
00937 }
00938 else {
00939 Tmp[1]->ApplyOp(BG[i] , Tmp[0] , i , op) ;
00940 R->PPlus(1 , Tmp[1]) ;
00941 }
00942 }
00943
00944 for (i=0; i<DIM; i++) R->ApplyOp(X->BC[i] , R , i , PROJECTION) ;
00945
00946 if (X->extended) {
00947 assert(Null) ;
00948 R->extended=true ;
00949 R->PPlus(X->ext,Null) ;
00950 R->ext=Null->InnerProd(X) ;
00951 Tmp[0]->extended=Tmp[1]->extended=false ;
00952 }
00953 }
00954
00955
00956
00957
00958
00959 template<class I,int DIM>
00960 PressureOperatorIII<I,DIM>::PressureOperatorIII() {
00961 Null=Tmp[0]=Tmp[1]=NULL ;
00962 do_restrict=do_patch=use_lifting_preconditioner=false ;
00963 }
00964
00965 template<class I,int DIM>
00966 void PressureOperatorIII<I,DIM>::NotUsing(I *X) { assert ((Tmp[0]!=X)&&(Tmp[1]!=X)&&(Null!=X)) ;}
00967
00968 template<class I,int DIM>
00969 double PressureOperatorIII<I,DIM>::DiagonalEntry(int *l , Wavelets *) {
00970 int i ;
00971 double d=0.0 ;
00972 for (i=0;i<DIM;i++) d += pow(4.0 , l[i]) ;
00973 return d;
00974 }
00975
00976 template<class I,int DIM>
00977 void PressureOperatorIII<I,DIM>::Preconditioner(I *X , I *R) {
00978 int i ;
00979 I *Y=X ;
00980
00981 if (use_lifting_preconditioner) { for (i=0; i<DIM; i++) R->ApplyOp( (i==0) ? X : R , i , INTERPOLET2LIFTING) ; Y=R ; }
00982
00983 HelmholtzDiagonalPreconditioner(Y,R,this,false) ;
00984
00985 if (use_lifting_preconditioner) for (i=0; i<DIM; i++) R->ApplyOp( R , i , LIFTING2INTERPOLET) ;
00986
00987 R->Ext.CopyData(&X->Ext) ;
00988 }
00989
00990 template<class I,int DIM>
00991 void PressureOperatorIII<I,DIM>::InversePreconditioner(I *X , I *R) {
00992 int i ;
00993 I *Y=X ;
00994
00995 if (use_lifting_preconditioner) { for (i=0; i<DIM; i++) R->ApplyOp( (i==0) ? X : R , i , INTERPOLET2LIFTING) ; Y=R ; }
00996
00997 InverseHelmholtzDiagonalPreconditioner(Y,R,this) ;
00998
00999 if (use_lifting_preconditioner) for (i=0; i<DIM; i++) R->ApplyOp( R , i , LIFTING2INTERPOLET) ;
01000
01001 R->Ext.CopyData(&X->Ext) ;
01002 }
01003
01004
01005
01006 template<class I,int DIM>
01007 void PressureOperatorIII<I,DIM>::Apply(I *X , I *R) {
01008 NotUsing(X) ;
01009 NotUsing(R) ;
01010
01011 int i ;
01012 int BG[DIM][2] ;
01013 int op = ( X->Ext.WC->InterpoletFlag && (X->Ext.WC->N<=2) ) ? DIVGRADFD4 : DIVGRAD ;
01014
01015
01016 R->SetBoundaryConditions(X) ;
01017 for (i=0; i<DIM; i++) {
01018 GetGeneralBoundaryConditions(X->Ext.BC[i] , BG[i]) ;
01019 if ((X->Ext.BC[i][0]==0) || (X->Ext.BC[i][1]==0)) assert(X->Ext.dimext==0) ;
01020 }
01021 Tmp[0]->Ext.dimext=Tmp[1]->Ext.dimext=X->Ext.dimext ;
01022
01023
01024 for (i=0; i<DIM; i++) Tmp[0]->ApplyOp(BG[i] , (i==0) ? X : Tmp[0] , i , PROJECTION) ;
01025
01026
01027 for (i=0; i<DIM; i++) {
01028 if (i==0) R->ApplyOp(BG[i] , Tmp[0] , i , op) ;
01029 else {
01030 Tmp[1]->ApplyOp(BG[i] , Tmp[0] , i , op) ;
01031 R->PPlus( Tmp[1] ) ;
01032 }
01033 }
01034
01035
01036 for (i=0; i<DIM; i++) R->ApplyOp(X->Ext.BC[i] , R , i , PROJECTION) ;
01037
01038 if (X->Ext.dimext) {
01039 assert(Null) ;
01040 R->Ext.dimext=1 ;
01041 R->PPlus(X->Ext.ext[0],Null) ;
01042 R->Ext.ext[0]=Null->InnerProd(X) ;
01043 Tmp[0]->Ext.dimext=Tmp[1]->Ext.dimext=0 ;
01044 }
01045
01046
01047 }
01048
01049
01050
01051
01052
01053 template<class I,int DIM>
01054 PressureOperatorIV<I,DIM>::PressureOperatorIV() {
01055 Null=Tmp[0]=Tmp[1]=NULL ;
01056 do_restrict=do_patch=use_lifting_preconditioner=false ;
01057
01058 }
01059
01060 template<class I,int DIM>
01061 void PressureOperatorIV<I,DIM>::NotUsing(I *X) { assert ((Tmp[0]!=X)&&(Tmp[1]!=X)&&(Null!=X)) ;}
01062
01063 template<class I,int DIM>
01064 double PressureOperatorIV<I,DIM>::DiagonalEntry(int *l , Wavelets *) {
01065 int i ;
01066 double d=0.0 ;
01067 for (i=0;i<DIM;i++) d +=pow(4.0 , l[i]) ;
01068 return d;
01069 }
01070
01071 template<class I,int DIM>
01072 void PressureOperatorIV<I,DIM>::Preconditioner(I *X , I *R) {
01073 int i ;
01074 I *Y=X ;
01075
01076 HelmholtzDiagonalPreconditioner(Y,R,this,false) ;
01077
01078 if (X->extended) R->ext=X->ext ;
01079 }
01080
01081 template<class I,int DIM>
01082 void PressureOperatorIV<I,DIM>::InversePreconditioner(I *X , I *R) {
01083 int i ;
01084 I *Y=X ;
01085
01086 InverseHelmholtzDiagonalPreconditioner(Y,R,this) ;
01087
01088 if (X->extended) R->ext=X->ext ;
01089 }
01090
01091
01092
01093 template<class I,int DIM>
01094 void PressureOperatorIV<I,DIM>::Apply(I *X , I *R) {
01095 NotUsing(X) ;
01096 NotUsing(R) ;
01097
01098 int i,j ;
01099 int BC[DIM][2] ;
01100
01101
01102 R->SetBoundaryConditions(X->BC) ;
01103 for (i=0; i<DIM; i++) {
01104 assert(X->BC[i][0]==-1) ;
01105 assert((X->BC[i][1]==-1) || (X->BC[i][1]==PERIODIC)) ;
01106
01107 if (X->BC[i][1]==PERIODIC) { BC[i][0]=-1, BC[i][1]=PERIODIC ;}
01108 else { BC[i][0]=BC[i][1]=0 ;}
01109 }
01110
01111 Tmp[0]->extended=Tmp[1]->extended=X->extended ;
01112
01113
01114 R->Set(0.0) ;
01115 R->ext=0 ;
01116 for (i=0; i<DIM; i++) {
01117 Tmp[0]->ApplyOp(X->BC[i] , X , i , FD14) ;
01118 for (j=0; j<DIM; j++) {
01119 Tmp[0]->ApplyOp( BC[j] , Tmp[0] , j , PROJECTION) ;
01120 Tmp[0]->ApplyOp(X->BC[j] , Tmp[0] , j , PROJECTION) ;
01121 }
01122
01123
01124
01125
01126
01127
01128
01129
01130 Tmp[0]->ApplyOp(X->BC[i] , Tmp[0] , i , FD14) ;
01131
01132 R->PPlus(1 , Tmp[0]) ;
01133 }
01134
01135 if (X->extended) {
01136 assert(Null) ;
01137 R->extended=true ;
01138 R->PPlus(X->ext,Null) ;
01139 R->ext=Null->InnerProd(X) ;
01140 Tmp[0]->extended=Tmp[1]->extended=false ;
01141 }
01142
01143 }
01144
01145
01146
01147
01148 template<class I,int DIM>
01149 PressureOperatorV<I,DIM>::PressureOperatorV() {
01150 Null=Tmp=NULL ;
01151 do_restrict=do_patch=use_lifting_preconditioner=false ;
01152
01153 }
01154
01155 template<class I,int DIM>
01156 void PressureOperatorV<I,DIM>::NotUsing(I *X) { assert ((Tmp!=X)&&(Null!=X)) ;}
01157
01158 template<class I,int DIM>
01159 double PressureOperatorV<I,DIM>::DiagonalEntry(int *l , Wavelets *) {
01160 return 1.0;
01161 }
01162
01163 template<class I,int DIM>
01164 void PressureOperatorV<I,DIM>::Preconditioner(I *X , I *R) {
01165 R->Copy(X) ;
01166 R->ext=X->ext ;
01167 }
01168
01169 template<class I,int DIM>
01170 void PressureOperatorV<I,DIM>::InversePreconditioner(I *X , I *R) {
01171 R->Copy(X) ;
01172 R->ext=X->ext ;
01173 }
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260 template<class I , int DIM>
01261 ConvectionOperator<I,DIM>::ConvectionOperator() {
01262 Tmp=NULL ;
01263 for (int i=0;i<DIM;i++) { U[i]=NULL ; }
01264 }
01265
01266 template<class I , int DIM>
01267 void ConvectionOperator<I,DIM>::NotUsing(I *X) { assert (Tmp!=X); assert (Tmp1!=X); }
01268
01269 template<class I , int DIM>
01270 double ConvectionOperator<I,DIM>::DiagonalEntry(int * , Wavelets *) { assert(0) ; return 0 ;}
01271
01272 template<class I , int DIM>
01273 void ConvectionOperator<I,DIM>::Preconditioner(I * , I * ) { assert(0) ; }
01274 template<class I , int DIM>
01275 void ConvectionOperator<I,DIM>::InversePreconditioner(I * , I * ) { assert(0) ; }
01276
01277 template<class I , int DIM>
01278 void ConvectionOperator<I,DIM>::Apply(I *X , I *R) {
01279 int i,j ;
01280
01281 NotUsing(X) ;
01282 NotUsing(R) ;
01283
01284 for (i=0; i<DIM; i++) {
01285 for (j=0; j<DIM; j++)
01286 Tmp->ApplyOp( U[0]->Ext.BC[j] , (j==0) ? X : Tmp , j , (j==i) ? FIRSTDERIVATIVE : PROJECTION) ;
01287
01288 for (j=0; j<DIM; j++)
01289 Tmp->ApplyOp( Tmp , j , INVERSETRANSFORM) ;
01290
01291 if (i==0)
01292 R->Mul(Tmp , U[i]) ;
01293 else {
01294 Tmp->Mul (Tmp , U[i]) ;
01295 R->PPlus(Tmp) ;
01296 }
01297 }
01298
01299 for (j=0; j<DIM; j++) R->ApplyOp( R ,j , TRANSFORM) ;
01300 for (j=0; j<DIM; j++) R->ApplyOp( X->Ext.BC[j] , R , j , PROJECTION) ;
01301
01302 }
01303
01304
01305 template<class I , int DIM>
01306 void ConvectionOperator<I,DIM>::ApplyFD(I *X , I *R) {
01307 int i,j,BG[DIM][2] ;
01308
01309 NotUsing(X) ;
01310 NotUsing(R) ;
01311
01312 for (j=0; j<DIM; j++) GetGeneralBoundaryConditions(X->Ext.BC[j],BG[j]) ;
01313
01314 for (j=0; j<DIM; j++) Tmp1->ApplyOp( BG[j] , (j==0) ? X : Tmp1 , j , PROJECTION) ;
01315
01316 for (i=0; i<DIM; i++) {
01317
01318 Tmp->ApplyOp( BG[i] , Tmp1 , i , FD14) ;
01319
01320 for (j=0; j<DIM; j++) Tmp->ApplyOp( Tmp , j , INVERSETRANSFORM) ;
01321
01322 if (i==0)
01323 R->Mul(Tmp , U[i]) ;
01324 else {
01325 Tmp->Mul (Tmp , U[i]) ;
01326 R->PPlus(Tmp) ;
01327 }
01328 }
01329
01330 for (j=0; j<DIM; j++) R->ApplyOp( R ,j , TRANSFORM) ;
01331 for (j=0; j<DIM; j++) R->ApplyOp( X->Ext.BC[j] , R , j , PROJECTION) ;
01332
01333 }
01334
01335
01336 template<class I , int DIM>
01337 void ConvectionOperator<I,DIM>::ApplyConservativeFast(int dir , I *R) {
01338 int i,j ;
01339
01340 for (i=0; i<DIM; i++)
01341 for (j=0; j<DIM; j++)
01342 assert(!U[j]->Ext.islifting[i]) ;
01343
01344 NotUsing(X) ;
01345 NotUsing(R) ;
01346
01347 for (i=0; i<DIM; i++) {
01348 Tmp->Mul(U[dir] , U[i]) ;
01349 for (j=0; j<DIM; j++) Tmp->ApplyOp( Tmp , j , TRANSFORM) ;
01350
01351 if (i==0) R->ApplyOp( U[0]->Ext.BC[i] , Tmp , i , FIRSTDERIVATIVE) ;
01352 else { Tmp->ApplyOp( U[0]->Ext.BC[i] , Tmp , i , FIRSTDERIVATIVE) ;
01353 R->Add(Tmp) ; }
01354 }
01355
01356 }
01357
01358
01359 template<class I , int DIM>
01360 void ConvectionOperator<I,DIM>::ApplyConservative(I *X , I *R) {
01361 int i,j,BG[DIM][2] ;
01362
01363 for (i=0; i<DIM; i++) assert(!X->Ext.islifting[i]) ;
01364
01365 NotUsing(X) ;
01366 NotUsing(R) ;
01367
01368 assert(Tmp) ;
01369 assert(Tmp1) ;
01370
01371 for (j=0; j<DIM; j++) GetGeneralBoundaryConditions(X->Ext.BC[j],BG[j]) ;
01372 for (j=0; j<DIM; j++) Tmp1->ApplyOp(BG[j] , (j==0) ? X : Tmp1 , j , PROJECTION) ;
01373
01374 for (j=0; j<DIM; j++) Tmp1->ApplyOp(BG[j], Tmp1, j, INVERSETRANSFORM) ;
01375
01376 for (i=0; i<DIM; i++) {
01377 Tmp->Mul(U[i] , Tmp1 ) ;
01378 for (j=0; j<DIM; j++) Tmp->ApplyOp( Tmp , j , TRANSFORM) ;
01379
01380 if (i==0) R->ApplyOp(BG[i] , Tmp , i , FIRSTDERIVATIVE) ;
01381 else { Tmp->ApplyOp(BG[i] , Tmp , i , FIRSTDERIVATIVE) ;
01382 R->PPlus(Tmp) ; }
01383 }
01384
01385 for (j=0; j<DIM; j++) R->ApplyOp(X->Ext.BC[j] , R , j , PROJECTION) ;
01386 }
01387
01388
01389
01390
01391
01392
01393 template<class I , int DIM>
01394 void ConvectionOperator<I,DIM>::ApplyConservativeFD(I *X , I *R) {
01395 int i,j,BG[DIM][2] ;
01396 bool change=false ;
01397
01398 for (i=0; i<DIM; i++) assert(!X->Ext.islifting[i]) ;
01399
01400 NotUsing(X) ;
01401 NotUsing(R) ;
01402
01403 assert(Tmp) ;
01404 assert(Tmp1) ;
01405
01406 for (j=0; j<DIM; j++) {
01407 GetGeneralBoundaryConditions(X->Ext.BC[j],BG[j]) ;
01408 Tmp1->ApplyOp(BG[j] , (j==0) ? X : Tmp1 , j , PROJECTION) ;
01409 }
01410
01411 for (j=0; j<DIM; j++) Tmp1->ApplyOp(BG[j] , Tmp1 , j , INVERSETRANSFORM) ;
01412
01413 for (i=0; i<DIM; i++) {
01414 Tmp->Mul(U[i] , Tmp1 ) ;
01415 for (j=0; j<DIM; j++) Tmp->ApplyOp(BG[j] , Tmp , j , TRANSFORM) ;
01416
01417 if (i==0) R->ApplyOp( BG[i] , Tmp , i , FD14) ;
01418 else { Tmp->ApplyOp( BG[i] , Tmp , i , FD14) ;
01419 R->PPlus(Tmp) ; }
01420 }
01421
01422 for (j=0; j<DIM; j++) R->ApplyOp(X->Ext.BC[j] , R , j , PROJECTION) ;
01423 }
01424
01425
01426
01427
01428
01429
01430 template<class I , int DIM>
01431 void ConvectionOperator<I,DIM>::ApplyConservativeWENO(I *X , I *R) {
01432 int i,j,BG[DIM][2] ;
01433
01434 for (i=0; i<DIM; i++) assert(!X->Ext.islifting[i]) ;
01435
01436 NotUsing(X) ;
01437 NotUsing(R) ;
01438
01439 assert(Tmp) ;
01440 assert(Tmp1) ;
01441
01442 for (j=0; j<DIM; j++) {
01443 GetGeneralBoundaryConditions(X->Ext.BC[j],BG[j]) ;
01444 Tmp1->ApplyOp(BG[j] , (j==0) ? X : Tmp1 , j , PROJECTION) ;
01445 }
01446
01447 for (j=0; j<DIM; j++) Tmp1->ApplyOp(BG[j] , Tmp1 , j , INVERSETRANSFORM) ;
01448
01449 for (i=0; i<DIM; i++) {
01450 Tmp->Mul(U[i] , Tmp1 ) ;
01451 for (j=0; j<DIM; j++) Tmp->ApplyOp(BG[j] , Tmp , j , TRANSFORM) ;
01452
01453 if (i==0) R->ApplyWENO(BG[i], Tmp, U[i], i , WENO5) ;
01454 else { Tmp->ApplyWENO(BG[i], Tmp, U[i], i , WENO5) ;
01455 R->PPlus(Tmp) ; }
01456 }
01457
01458 for (j=0; j<DIM; j++) R->ApplyOp(X->Ext.BC[j] , R , j , PROJECTION) ;
01459
01460 }
01461
01462
01463
01464
01465
01466
01467 template<class I , int DIM>
01468 void ConvectionOperator<I,DIM>::ApplyConservativeWENOUniformData(UniformData<DIM> *X , UniformData<DIM> *R, bool trafo) {
01469 int i,j,dir,BG[DIM][2],J[DIM] ;
01470
01471 NotUsing(X) ;
01472 NotUsing(R) ;
01473
01474 assert(Tmp) ;
01475 assert(Tmp1) ;
01476
01477 X->ba->CalcLevel(J) ;
01478
01479 for (j=0; j<DIM; j++) {
01480 assert(X->Ext.ismultiscale[j]== false) ;
01481 assert(X->Ext.BC[j][1]==PERIODIC) ;
01482 GetGeneralBoundaryConditions(X->Ext.BC[j],BG[j]) ;
01483 }
01484 Tmp1->Copy(X) ;
01485
01486
01487 R->CopyExtensions(Tmp1) ;
01488 R->Set(0.0) ;
01489
01490 for (dir=0; dir<DIM; dir++) {
01491 Tmp->Mul(U[dir] , Tmp1 ) ;
01492
01493 if (trafo) {
01494 for (i=0; i<DIM; i++)
01495 if (i!=dir) Tmp->ApplyOp(BG[i], Tmp, i, TRANSFORM) ;
01496 }
01497
01498 Matrix<double,DIM>::iterator s, Xend=(*X->ba).end() ;
01499 int b=X->ba->b[dir] , e=X->ba->e[dir] ;
01500
01501 IndexSet IS(2) ; IS.a[0]=b; IS.e[0]=e; IS.nr=1 ;
01502
01503 for (s=(*X->ba).begin(dir) ; s<=Xend ; ++s) {
01504 double *Fs=_DATAMATRIX_BUFFER_s, *Ft=_DATAMATRIX_BUFFER_t, *Fr=_DATAMATRIX_BUFFER_q ;
01505
01506 int *i=&s.i[dir] ;
01507 for ((*i)=b; (*i)<=e; (*i)++) {
01508 Fs[(*i)-b]=(*Tmp->ba) [s] ;
01509 Fr[(*i)-b]=(*U[dir]->ba)[s] ;
01510 }
01511
01512 IS.VecApplyWENO(Ft,Fs, Fr, BG[dir], J[dir], 3 , X->Ext.XE[dir]-X->Ext.XA[dir]) ;
01513
01514 for ((*i)=b; (*i)<=e; (*i)++) (*Tmp->ba)[s] = Ft[(*i)-b] ;
01515 }
01516
01517 if (trafo) {
01518 for (i=0; i<DIM; i++)
01519 if (i!=dir) Tmp->ApplyOp(BG[i], Tmp, i, INVERSETRANSFORM) ;
01520 }
01521
01522 R->PPlus(Tmp) ;
01523
01524 }
01525
01526
01527 }
01528
01529
01530 template<class I,int DIM>
01531 SpaceTimeOperator<I,DIM>::SpaceTimeOperator() {
01532 Tmp=Tmp2=NULL ;
01533 use_lifting_preconditioner=false ;
01534 }
01535
01536 template<class I,int DIM>
01537 void SpaceTimeOperator<I,DIM>::Apply(I *X , I *Result) {
01538
01539 int i,BG[DIM][2] ;
01540 for (i=0; i<DIM; i++) GetGeneralBoundaryConditions(X->Ext.BC[i],BG[i]) ;
01541 for (i=0; i<DIM; i++) Tmp2->ApplyOp(BG[i], (i==0) ? X : Tmp2, i , PROJECTION) ;
01542 Result->ApplyOp(BG[0], Tmp2, 0, FD11) ;
01543 for (i=1; i<DIM; i++) {
01544 Tmp ->ApplyOp(BG[i], Tmp2, i, FD24) ;
01545 Result->MMinus(1.0 , Tmp) ;
01546 }
01547 for (i=0; i<DIM; i++) Result->ApplyOp(X->Ext.BC[i], Result, i , PROJECTION) ;
01548
01549 }
01550
01551 template<class I,int DIM>
01552 void SpaceTimeOperator<I,DIM>::DiagonalScale(I *X, bool inverse) {
01553
01554
01555 Matrix< vector<double> * , DIM>::iterator it(&X->ba->d),dend=X->ba->d.end() ;
01556 AdaptiveDataArray<DIM>::DataVector *vx ;
01557 size_t i,n ;
01558 for (it=X->ba->d.begin(); it<=dend; ++it) {
01559 vx=X->ba->d[it] ; n=(*vx).size() ;
01560
01561
01562 double diag=pow(2.0 , it.i[0]) ;
01563 for (i=1; i<DIM; i++) diag += pow(4.0 , it.i[i]) ;
01564 if (!inverse) diag=1.0/diag ;
01565 for (i=0; i<n; i++) (*vx)[i] *= diag ;
01566 }
01567
01568 }
01569
01570 template<class I,int DIM>
01571 void SpaceTimeOperator<I,DIM>::Preconditioner(I *X , I *R) {
01572 int i;
01573 R->Copy(X) ;
01574 if (use_lifting_preconditioner) for (i=1; i<DIM; i++) R->ApplyOp(R->Ext.BC[i], R, i, INTERPOLET2LIFTING) ;
01575 DiagonalScale(R,false) ;
01576 if (use_lifting_preconditioner) for (i=1; i<DIM; i++) R->ApplyOp(R->Ext.BC[i], R, i, LIFTING2INTERPOLET) ;
01577 }
01578
01579 template<class I,int DIM>
01580 void SpaceTimeOperator<I,DIM>::InversePreconditioner(I *X , I *R) {
01581 int i;
01582 R->Copy(X) ;
01583 if (use_lifting_preconditioner) for (i=1; i<DIM; i++) R->ApplyOp(R->Ext.BC[i], R, i, INTERPOLET2LIFTING) ;
01584 DiagonalScale(R,true) ;
01585 if (use_lifting_preconditioner) for (i=1; i<DIM; i++) R->ApplyOp(R->Ext.BC[i], R, i, LIFTING2INTERPOLET) ;
01586 }
01587
01588 template<class I,int DIM>
01589 void SpaceTimeOperator<I,DIM>::NotUsing(I *X) { assert ( (Tmp!=X) && (Tmp2!=X)) ;}
01590
01591 template<class I,int DIM>
01592 double SpaceTimeOperator<I,DIM>::DiagonalEntry(int * , Wavelets *) { return 1; }
01593 #endif