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