Department of Scientific Computing   
Institute for Numerical Simulation   
University of Bonn   
Documentation
Download
Programming References
Bug Reports / Suggestions
FAQ
Authors
Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

Operators.hpp

00001 //
00002 // Operators
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 //double RealResidual(Data *) ;
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 // Attention: in the following classes Tmp points to to some auxiliary data used for the evaluation of the operators
00035 // Tmp may be uninitialized. Note, this moves the memory management completely to the calling program.
00036 // In particulary one has to assert that the calling program/subroutine does not use the Operator's (*Tmp) Data.
00037 // It is strongly recommended to verify this condition using the NotUsing() function
00038 // 
00039 
00040 // scalar: par[0]*id + par[1]*dxx  + par[2]*dyy + ...
00041 //template<int DIM>
00042 //void Helmholtz(AdaptiveData<DIM> *X, double *par, AdaptiveData<DIM> *Result, AdaptiveData<DIM> *Tmp, AdaptiveData<DIM> *Tmp2) ;
00043 
00044 //template<int DIM>
00045 //void Helmholtz(UniformData<DIM>  *X, double *par, UniformData<DIM>  *Result, UniformData<DIM>  *Tmp, UniformData<DIM>  *Tmp2) ;
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 // To solve singular linear systems one may augment the operator
00058 // for singular problems one may also provide a vector which spans the null space (or an approximation to)
00059 // for the solution of Dirichlet-problems one can define faces on which Dirichlet conditions shall hold;
00060 // to this end one has to set the attribute BC[i][k]:=0 OF THE OPERATOR ! <br>
00061 // this forces the Apply(*X,*R) function just to copy the coefficients for boundary wavelets
00062 // from *X to *R
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   // (optional) vector which spanns the null space 
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 // IntegroDifferentialOperator 
00149 //
00150 // Pa[0]*u(x) + Pa[1]*(Du)(x) + Pa[2]*int_y KY(x,y)u(y)dy KX(x)
00151 //
00152 template<class I , int DIM>
00153 struct TensorIntegroDifferentialOperator : public Operator<I , DIM> {
00154   double par[3]           ; // parameters
00155   Operator<I , DIM> * D   ; // Differential Operator
00156   LevelAdaptiveData<DIM>  *KX,*KY ; // Kernel of Integral operator
00157   I                  *Tmp ; // Only required if D != NULL               
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 //  Null is approximation of the (right) null space of the operator
00195 //  In Apply: if (X->extended) then
00196 //  R->ext = Null->InnerProd(X) ;
00197 //  and R->PPlus(X->ext,Null)   ;
00198 //  hence, the sattlepoint formulation of the linear operator is evaluated
00199 //  which overcomes the difficulties in a lacking solvability constraint
00200 //  for singular linear systems
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 // div*grad
00236 // if !periodic BC: Vel_BC=(-1,-1),(-1,-1) , Press_BC=(1,1),(1,1)
00237 // Null is approximation of the (right) Null space of the operator
00238 // In Apply: if (X->extended) then
00239 // R->ext = Null->InnerProd(X) ;
00240 // and R->PPlus(X->ext,Null)   ;
00241 // hence, the sattlepoint formulation of the linear operator is evaluated
00242 // which overcomes the difficulties in a lacking solvability constraint
00243 // for singular linear systems
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 // Convective term:
00281 // Apply:                 scalar (grad X)*U
00282 // ApplyConservative:     scalar div(UX)
00283 // ApplyConservativeFast: scalar div(UU[i]) 
00284 //
00287 template<class I , int DIM>
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 // Operators: Implementations //
00320 //                            //
00322 
00323 //
00324 // Helmholtz
00325 //
00326 // Helmholtz evaluates the general Helmholtz-Operator
00327 //
00328 // Pa[0]*u + Pa[1]*uxx + Pa[2]*uyy + Pa[3]*uzz + ....
00329 // projection on basis WITH SAME boundary conditions as X
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) { // all parameters vanish ...
00349    R->Set(0.0) ;
00350    R->SetBoundaryConditions(X) ;
00351    return ;
00352  }
00353  if (last==0) { // just the first parameter not ...
00354    R->Mul(X,par[0]) ;
00355    R->SetBoundaryConditions(X) ;
00356    return ;
00357  }
00358 
00359  // transform to interpolets if necessary: in any case *tmp3 points to the (modified) argument "X"
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  // here: tmp3 = X or tmp2 
00370 
00371 
00372  // FD Operators required, but, application of FD requires general BC (-1,-1) or (-1,10)
00373  // in any case tmp2 points to the modified data "X"
00374  if ( X->Ext.WC->InterpoletFlag && (X->Ext.WC->N<=4) ) {
00375    //op=FD24 ;
00376    op = (X->Ext.WC->N == 2) ? FD22 : FD24II ; //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  // all parameters are just zero:
00395  //if (last<=0) {
00396  //  R->Set(0.0) ;
00397  //  R->SetBoundaryConditions(X) ;
00398  //  return ;
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  // transform to Lifting
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 // Preconditioner::AdaptiveData<DIM>
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  // diagonal scaling
00434  // iterate over all level
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    // calc diagonal entry
00439    diag=O->DiagonalEntry( it.i , X->G->WC) ;
00440 
00441    if (inverse) diag=1/diag ;
00442 
00443 // diag=1.0 ;
00444    for (i=0; i<n; i++) (*vr)[i] = (*vx)[i]/diag ;
00445  }
00446 
00447  /*
00448  bool neumann=true ;
00449  for (i=0; i<DIM; i++) if ((X->Ext.BC[i][0]!=1)||(X->Ext.BC[i][1]!=1)) neumann=false ;
00450  if (neumann) {
00451    assert(0) ; 
00452    int    e[DIM],ld   ;
00453    double mx=0.0,z ;
00454    unsigned long j[DIM] ;
00455 
00456    AdaptiveGrid<DIM>::ProjectionGrid           *pg=X->G->BasisPG[0] ;
00457    AdaptiveGrid<DIM>::ProjectionGrid::iterator  pgit ;
00458 
00459    AdaptiveLevels                     *als  ;
00460    AdaptiveLevelsIndex                *ali  ;
00461    AdaptiveLevels::AdaptiveL          *al   ;
00462    AdaptiveLevels::AdaptiveL::iterator alit ; 
00463    psg=(*pg)[&X->G->Level0[1]] ;
00464 
00465    for (i=1; i<DIM; i++) {
00466      e[i]= 1<<X->G->Level0[i] ;
00467     }
00468 
00469    for (psgit=(*psg).begin(); psgit != (*psg).end(); psgit++) {
00470 
00471       als=(*psgit).second ;
00472       for (i=1; i<DIM; i++) j[i]=(*psgit).first.i[i-1] ;
00473 
00474       ld=X->G->Level0[0] ;
00475       e[0]=1<<ld ;
00476       al=(*als)[ld] ;
00477 
00478       for (alit=(*al).begin(); alit != (*al).end(); alit++) {
00479         j[0]=(*alit).first ;
00480         z=fabs( (*R->ba->d[X->G->Level0])[(*alit).second]) ;
00481         for (i=0;i<DIM;i++) if ((j[i]==1)||(j[i]==(unsigned long)(e[i]-1))) mx = (mx>z) ? mx : z ;
00482        }
00483      } // next psgit
00484   }
00485  */
00486 }
00487 
00488 
00489 //
00490 // Preconditioner::UniformData<DIM>
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 // Preconditioner::LevelAdaptiveData<DIM>
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)/*&&(Null!=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     //  R->CopyFaces(X,BC) ;
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]) ; //exp(log(1<< l[i])*2.0) ;
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  int  i ;
00613  I *Y=X ;
00614  if (use_lifting_preconditioner) {
00615    for (i=0; i<DIM; i++) R->ApplyOp( (i==0) ? X : R , i , INTERPOLET2LIFTING) ;
00616    Y=R ;
00617   }
00618 
00619  HelmholtzDiagonalPreconditioner<DIM>(Y,R,this,false) ;
00620 
00621  if (use_lifting_preconditioner)
00622    for (i=0; i<DIM; i++) R->ApplyOp( R , i , LIFTING2INTERPOLET) ;
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  int  i ;
00633  I *Y=X ;
00634  if (use_lifting_preconditioner) {
00635    for (i=0; i<DIM; i++) R->ApplyOp( (i==0) ? X : R , i , INTERPOLET2LIFTING) ;
00636    Y=R ;
00637   }
00638 
00639  InverseHelmholtzDiagonalPreconditioner<I,DIM>(Y,R,this) ;
00640 
00641  if (use_lifting_preconditioner) 
00642    for (i=0; i<DIM; i++) R->ApplyOp( R , i , LIFTING2INTERPOLET) ;
00643   */
00644 }
00645 
00646 //
00647 // IntegroDifferentialOperator 
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]) ; //exp(log(1<< l[i])*2.0) ;
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 // TensorIntegroDifferentialOperator 
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]) ; //exp(log(1<< l[i])*2.0) ;
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 // PressureOperatorI
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   // for (int i=0; i<DIM; i++) XL[i]=1.0 ;
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] ) ; //exp(log(1<< l[i])*2.0) ;
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  // treat BC
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  // imbed to general BCs
00831  for (i=0; i<DIM; i++) Tmp[0]->ApplyOp(BG[i] , (i==0) ? X : Tmp[0] , i , PROJECTION) ;
00832 
00833  // Build up div*grad
00834  for (i=0; i<DIM; i++) {
00835    if (i==0) {
00836           R->ApplyOp(BG[i] , Tmp[0] , i , op) ;
00837           //R->Mul(1./(XL[0]*XL[0])) ;
00838     }
00839    else {
00840      Tmp[1]->ApplyOp(BG[i] , Tmp[0] , i , op) ;
00841      R->PPlus(1 /*./(XL[i]*XL[i])*/ , Tmp[1]) ;
00842     }
00843  } 
00844  // project to pressure BCs
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 // PressureOperatorII
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   //  for (int i=0; i<DIM; i++) XL[i]=1.0 ;
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]) ; //exp(log(1<< l[i])*2.0) ;
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 // PressureOperator for consistent Laplacian with homg Neumann/periodic boundary conditions
00909 // NO STABILIZATION.
00910 // !!! solvability problems for extended==false and DIVGRADFD4NOSTAB !!!
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  // treat BC
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  // imbed to general BCs
00930  for (i=0; i<DIM; i++) Tmp[0]->ApplyOp(BG[i] , (i==0) ? X : Tmp[0] , i , PROJECTION) ;
00931 
00932  // Build up div*grad
00933  for (i=0; i<DIM; i++) {
00934    if (i==0) {
00935           R->ApplyOp(BG[i] , Tmp[0] , i , op) ;
00936           //R->Mul(1./(XL[0]*XL[0])) ;
00937     }
00938    else {
00939      Tmp[1]->ApplyOp(BG[i] , Tmp[0] , i , op) ;
00940      R->PPlus(1 /*./(XL[i]*XL[i])*/ , Tmp[1]) ;
00941     }
00942  } 
00943  // project to pressure BCs
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 // PressureOperatorIII
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 // PressureOperator for consistent Laplacian with homg Neumann/periodic boundary conditions
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  // treat BC
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  // imbed to general BCs
01024  for (i=0; i<DIM; i++) Tmp[0]->ApplyOp(BG[i] , (i==0) ? X : Tmp[0] , i , PROJECTION) ;
01025 
01026  // build up div*grad
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  // project to pressure BCs
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 // PressureOperatorIV
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   //  for (int i=0; i<DIM; i++) XL[i]=1.0 ;
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 +=/*1./(XL[i]*XL[i])**/pow(4.0 , l[i]) ; //exp(log(1<< l[i])*2.0) ;
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 // PressureOperator for consistent Laplacian with homg Neumann/periodic boundary conditions
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  // treat BC
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  // Build up div*grad
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    int A[2]={0,0},J[2]={6,6},E[2]={64,64} ;
01125    Matrix<double,2> MM(A,E) ;
01126    Tmp[0]->ToUniform(&MM,J) ;
01127    if ((i==1)&& (debugRefine!=0)) { MM.WriteMATLAB("R1") ;exit(-1) ;}
01128    */
01129 
01130    Tmp[0]->ApplyOp(X->BC[i] , Tmp[0] , i , FD14) ;
01131 
01132    R->PPlus(1/*./(XL[i]*XL[i])*/ , 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 // PressureOperatorV
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   // for (int i=0; i<DIM; i++) XL[i]=1.0 ;
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 // PressureOperator for consistent Laplacian with homg Neumann/periodic boundary conditions
01177 template<class I,int DIM>
01178 void PressureOperatorV<I,DIM>::Apply(I *X , I *R) {
01179  NotUsing(X) ;
01180  NotUsing(R) ;
01181 
01182  int i,j ;
01183  int BC[DIM][2] ;
01184 
01185  for (i=0; i<DIM; i++) BC[i][0]=BC[i][1]=-1 ;
01186 
01187  //Tmp[0]->extended=Tmp[1]->extended=X->extended ;
01188 
01189  // Build up div*grad
01190  R->Set(0.0) ;
01191  for (i=0; i<DIM; i++) {
01192    int op[DIM]={NOOPERATION , NOOPERATION},re[DIM] ;
01193    op[i]=FD14 ;
01194    Tmp->ba->TensorMatrixOperation(BC,X->ba,BC,X->WC,applyOp,op,re) ;
01195    Tmp->extended=X->extended ;
01196 
01197    Matrix<double,DIM>::iterator s(Tmp->ba) ;
01198    for (s=(*Tmp->ba).begin(); s<=(*Tmp->ba).end(); ++s) 
01199      for (j=0; j<DIM; j++) if ((s.i[j]==0) || (s.i[j]==Tmp->ba->e[j])) (*Tmp->ba)[s]=0.0 ;
01200 
01201    op[i]=FD14 ;
01202    Tmp->ba->TensorMatrixOperation(BC,Tmp->ba,BC,X->WC,applyOp,op,re) ;
01203 
01204    R->PPlus(1 , Tmp) ;
01205  } 
01206 
01207  if (X->extended) {
01208    assert(Null) ;
01209    R->extended=true ;
01210    R->PPlus(X->ext,Null) ;
01211    R->ext=Null->InnerProd(X) ;
01212    Tmp->extended=false ;
01213  }
01214 
01215 }
01216 
01217 template<class I,int DIM>
01218 void PressureOperatorV<I,DIM>::Applyi(I *X , I *R,int i) {
01219  NotUsing(X) ;
01220  NotUsing(R) ;
01221 
01222  int j ;
01223  int BC[DIM][2] ;
01224 
01225  for (j=0; j<DIM; j++) BC[j][0]=BC[j][1]=-1 ;
01226 
01227  //Tmp[0]->extended=Tmp[1]->extended=X->extended ;
01228 
01229  // Build up div*grad
01230  R->Set(0.0) ;
01231 
01232    int op[DIM]={NOOPERATION , NOOPERATION},re[DIM] ;
01233    op[i]=FD12 ;
01234    Tmp->ba->TensorMatrixOperation(BC,X->ba,BC,X->WC,applyOp,op,re) ;
01235    Tmp->extended=X->extended ;
01236 
01237    Matrix<double,DIM>::iterator s(Tmp->ba) ;
01238    for (s=(*Tmp->ba).begin(); s<=(*Tmp->ba).end(); ++s) 
01239      for (j=0; j<DIM; j++) if ((s.i[j]==0) || (s.i[j]==Tmp->ba->e[j])) (*Tmp->ba)[s]=0.0 ;
01240 
01241    Tmp->ba->TensorMatrixOperation(BC,Tmp->ba,BC,X->WC,applyOp,op,re) ;
01242 
01243    R->PPlus(1 , Tmp) ;
01244 
01245 
01246  if (X->extended) {
01247    assert(Null) ;
01248    R->extended=true ;
01249    R->PPlus(X->ext,Null) ;
01250    R->ext=Null->InnerProd(X) ;
01251    Tmp->extended=false ;
01252  }
01253 }
01254 */
01255 
01256 //
01257 // ConvectiveOperator
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 /*, XL[i]=1.0*/; }
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 // ApplyConservativeFD was instable in ModonsAdap/Merging problem
01391 // on the other hand, it worked well for the simple transport problem ....
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   // *this=0 ;
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] ; // F
01509         Fr[(*i)-b]=(*U[dir]->ba)[s] ; // roespeed
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   //for (j=0; j<DIM; j++) R->ApplyOp(BG[j] ,  R , j , TRANSFORM) ;
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  // iterate over all level
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    // calc diagonal entry
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

Generated at Mon Aug 19 10:02:32 2002 for AWFD by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001