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  

Adaptive1DMatrix.cc

00001 //: Adaptive1D.cc
00002 
00003 #include "Adaptive1D.hpp"
00004 #include "Buffer.hpp"
00005 
00006 //
00007 //  MatVec (double *T1,IndexSet *IT,int *BCT  ,  double *F,IndexSet *IF,int *BCF,int l)
00008 //  multiplies *This(l)  by the adaptive vektor (F,IF,BCF). Only the the components from IT are calculated 
00009 //  All other components are left unchanged
00010 // 
00011 //  In the current implementation, the complete matrix-vector--product is performed, and thereafter just the
00012 //  components from IT are copied to the final result
00013 //  This avoids the clumsy checks for 'j \in IT ?'
00014 //
00015 
00016 extern int debugRefine ;
00017 void OperatorMatrix::MatVec (double *T1,IndexSet *IT,int *BCT  ,  double *F,IndexSet *IF,int *BCF,
00018                              int l,int clflag, double DX, doubleBuffer *buf)
00019 {
00020  if (IT->nr==0) return ;
00021 
00022  Matrix2D *CL,*CLT,*CR,*CRT ;
00023  int       l2,M,N,l21       ;
00024  int       KL0,KL1,KR0,KR1,BL0,BL1,BR0,BR1 ;
00025  int       i,j,r,e,je,l24   ; 
00026  double    q=pow((1<<l)/DX , power),x,*b,*T=buf->lock(); 
00027  assert(T) ;
00028 
00029  CL=CLT=CR=CRT=NULL ;
00030  KL0=KL1=KR0=KR1=BL0=BL1=BR0=BR1=0 ;
00031 
00032  // get dimensions of (sub-)matrices
00033  l2 =M=N= 1<<l ; // {0,..,M}x{0,..,N}-matrix
00034  l21=l2-1 ;
00035  l24=4*l2 ;
00036 
00037  if (IsWT) M-- ;
00038  if (IsWF) N-- ;
00039 
00040  // clear result
00041  if (clflag) IT->VecClear(T)   ;
00042        else  IT->VecCopy(T,T1) ;
00043  
00044  // left boundary
00045  if (BCT[1]!=PERIODIC) {
00046 
00047    assert(BCF[1]!=PERIODIC) ;
00048 
00049    CL =&AL [BCT[0]+1][BCF[0]+1] ; // sub blocks
00050    CLT=&ALT[BCT[0]+1][BCF[0]+1] ;
00051    CR =&AR [BCT[1]+1][BCF[1]+1] ;
00052    CRT=&ART[BCT[1]+1][BCF[1]+1] ;
00053 
00054    KL0=CL->size[0] ; KL1=CLT->size[1] ;
00055    KR0=CR->size[0] ; KR1=CRT->size[1] ;
00056 
00057    BL1=CL->size[1]-1 ; BL0=KL0+CLT->size[0]-1 ;
00058    BR1=CR->size[1]-1 ; BR0=KR0+CRT->size[0]-1 ;
00059 
00060    assert((KL0+0+KR0)<=M) ;
00061 
00062    // very small matrices are build up explicitely 
00063    if ((BL0+1+KR0)>=M) {
00064      int in[2],im[2] ;
00065      Matrix2D A(M+1,N+1) ;
00066      // copy inner parts, CL and CR
00067      for (i=KL0; i<=M-KR0; i++) for (j=-O; j<=U  ; j++) { in[0]=i; in[1]=i+j; A[in]=a[U-j]    ; }
00068      for (i=0  ; i<KL0   ; i++) for (j= 0; j<=BL1; j++) { in[0]=i; in[1]=  j; A[in]=(*CL)[in] ; }
00069      for (i=0  ; i<KR0   ; i++) for (j= 0; j<=BR1; j++) { im[0]=i; im[1]=j; in[0]=M-KR0+1+i; in[1]=N-BR1+j; A[in]=(*CR)[im] ; }
00070      //A.Print() ; exit(-1)  ;
00071      for (r=0; r<IF->nr; r++) A.AdaptiveAPlusBMatVec (1.0,q,F,T, IF->a[r], IF->e[r] ) ;
00072      goto ende ;
00073    }
00074    
00075    KR0=M-KR0 ; KR1=N-KR1 ;
00076    BR0=M-BR0 ; BR1=N-BR1 ;
00077 
00078    // treat upper left and lower right block separately, since they may have some overlap
00079    for (r=0; r<IF->nr; r++) {
00080      CL->AdaptiveAPlusBMatVec (1.0,q,F,T, IF->a[r], min(IF->e[r],BL1) ) ;
00081      if (IF->e[r]>=BL1) break ;
00082    }    
00083 
00084    for (r=IF->nr-1; r>=0; r--) {
00085      CR->AdaptiveAPlusBMatVec (1.0,q,&F[BR1],&T[KR0+1],max(IF->a[r]-BR1,0)  , min(IF->e[r],N)-BR1) ;
00086      if (IF->a[r]<=BR1) break ;
00087    }
00088 
00089    r=0 ;
00090    while (r<IF->nr) {
00091      CLT->AdaptiveAPlusBMatVec(1.0,q,F,&T[KL0],IF->a[r],min(IF->e[r],KL1-1)) ;
00092      e=min(IF->e[r],BL1);
00093      for (i=max(KL1,IF->a[r]);i<=e;i++) {
00094        x=F[i]*q ;
00095        for (j=max(KL0,i-U);j<=min(KR0,i+O);j++) T[j] +=a[j-i+U]*x ;
00096      }
00097      if(e==BL1) goto innen ; // ATTENTION: i is either F->a[r], if e< BL1     OR     i==BL1+1 if e==BL1
00098      r++ ;
00099     }
00100  } else { // periodic BC
00101    r=0 ;
00102    while (r<IF->nr) {
00103      e=min(IF->e[r],BL1) ;
00104      for (i=IF->a[r];i<=e;i++) {
00105        x=F[i]*q ; je=i+O+l24; b=&a[-i+U-l24] ;
00106        for (j=i-U+l24;j<=je;j++) T[j&l21] +=b[j]*x ;
00107      }
00108      if(e==BL1) goto innen ;
00109      r++ ;
00110    }
00111  }
00112 
00113 //
00114 // Inneres 
00115  i=-MAXINT ; // should never be executed (if  r < IF->nr)
00116 innen: ;
00117 
00118  // optimized inner loops
00119  if ((U==4) && (O==4)) {
00120    if (fabs(a[0]+a[8])<1e-15) {OperatorMatrixInnerLoop44Odd (&i,&r,F,T,IF,BR1-1,a,q);goto rechts;}
00121    if (fabs(a[0]-a[8])<1e-15) {OperatorMatrixInnerLoop44Even(&i,&r,F,T,IF,BR1-1,a,q);goto rechts;}
00122   }
00123  if ((U==1) && (O==2)) {
00124    if (fabs(a[0]+a[3])<1e-15) {OperatorMatrixInnerLoop12Odd (&i,&r,F,T,IF,BR1-1,a,q);goto rechts;}
00125    if (fabs(a[0]-a[3])<1e-15) {OperatorMatrixInnerLoop12Even(&i,&r,F,T,IF,BR1-1,a,q);goto rechts;}
00126   }
00127 
00128  if ((U==7) && (O==6)) {
00129    if (fabs(a[0]+a[13])<1e-15) {OperatorMatrixInnerLoop76Odd (&i,&r,F,T,IF,BR1-1,a,q);goto rechts;}
00130    if (fabs(a[0]-a[13])<1e-15) {OperatorMatrixInnerLoop76Even(&i,&r,F,T,IF,BR1-1,a,q);goto rechts;}
00131   }
00132 
00133  // ordinary inner loop
00134  while (r<IF->nr) {
00135    e=min(IF->e[r],BR1-1) ;
00136    while (i<=e) {
00137      x=F[i]*q ; b=&a[-i+U] ; je=i+O ;
00138      for (j=i-U;j<=je;j++) T[j] +=b[j]*x ; // Bem. leider sind die 'gemischten' OperatorMatrizen <dxPsi,Phi> nicht (anti-)symm. !!
00139      i++ ; 
00140    } 
00141    if (e==BR1-1) goto rechts ;
00142    r++; 
00143    i=IF->a[r] ;
00144  }
00145 
00146 // right boundary
00147 rechts: ;
00148  if (BCT[1]!=PERIODIC) {
00149    while (r < IF->nr) {
00150      CRT->AdaptiveAPlusBMatVec(1.0,q,&F[KR1+1],&T[BR0],max(IF->a[r]-KR1-1,0),min(IF->e[r],N)-KR1-1) ;
00151      for (i=max(i,IF->a[r]);i<=min(IF->e[r],KR1);i++) {
00152        x=F[i]*q ;
00153        for (j=max(KL0,i-U);j<=min(KR0,i+O);j++) T[j] +=a[j-i+U]*x ;
00154       }
00155      r++ ;
00156    }
00157  } else {  // periodic BC
00158    while (r < IF->nr) {
00159      for (i=max(i,IF->a[r]);i<=min(IF->e[r],l2-1);i++) {
00160        x=F[i]*q ; je=i+O+l24; b=&a[-i+U-l24] ;
00161        for (j=i-U+l24;j<=je;j++) T[j&l21] +=b[j]*x ;
00162       }
00163      r++ ;
00164    }
00165  }
00166 
00167 ende:;
00168  // copy result 
00169  IT->VecCopy(T1,T) ;
00170  buf->unlock() ;
00171 }
00172 
00174 //                                                          //
00175 //  Fast versions of inner loop for OperatorMatrix::MatVec  //
00176 //                                                          //
00177 //     for Interpolets(6) only up to now                    //
00178 //                                                          //
00180 
00181 void OperatorMatrixInnerLoop44Odd(int *ii  , int *rr   , double *F, double *T , IndexSet *IF , 
00182                                   int BR11 , double *a , double q) {
00183  int r=*rr,i=*ii,e ;
00184  double x,y/*,*Ti*/ ;
00185 
00186  while (r<IF->nr) {
00187    e=min(IF->e[r],BR11) ;
00188    while (i<=e) {
00189      x=F[i]*q ;
00190      y=a[0]*x ; T[i-4] +=y ; T[i+4] -=y ;
00191      y=a[1]*x ; T[i-3] +=y ; T[i+3] -=y ;
00192      y=a[2]*x ; T[i-2] +=y ; T[i+2] -=y ;
00193      y=a[3]*x ; T[i-1] +=y ; T[i+1] -=y ;
00194      /*
00195      Ti=&T[i] ;
00196      y=a[0]*x ; Ti[-4] +=y; Ti[4] -=y ;
00197      y=a[1]*x ; Ti[-3] +=y; Ti[3] -=y ;
00198      y=a[2]*x ; Ti[-2] +=y; Ti[2] -=y ;
00199      y=a[3]*x ; Ti[-1] +=y; Ti[1] -=y ;
00200      */
00201      i++ ;
00202    }
00203    if (e==BR11) { *ii=i , *rr=r ; return ; }
00204    r++; 
00205    i=IF->a[r] ;
00206  }
00207 
00208 *ii=i , *rr=r ;
00209 }
00210 
00211 
00212 void OperatorMatrixInnerLoop44Even(int *ii  , int *rr   , double *F, double *T , IndexSet *IF , 
00213                                    int BR11 , double *a , double q) {
00214  int r=*rr,i=*ii,e ;
00215  double x,y ;
00216  
00217  while (r<IF->nr) {
00218    e=min(IF->e[r],BR11) ;
00219    while (i<=e) {
00220      x=F[i]*q ;
00221      y=a[0]*x ; T[i-4] +=y ; T[i+4] +=y ;
00222      y=a[1]*x ; T[i-3] +=y ; T[i+3] +=y ;
00223      y=a[2]*x ; T[i-2] +=y ; T[i+2] +=y ;
00224      y=a[3]*x ; T[i-1] +=y ; T[i+1] +=y ;
00225      T[i] +=a[4]*x ;
00226      i++ ;
00227    }
00228    if (e==BR11) { *ii=i , *rr=r ; return ; }
00229    r++; 
00230    i=IF->a[r] ;
00231  }
00232 
00233 *ii=i , *rr=r ;
00234 }
00235 
00236 
00237 void OperatorMatrixInnerLoop12Odd(int *ii  , int *rr   , double *F, double *T , IndexSet *IF , 
00238                                   int BR11 , double *a , double q) {
00239  int r=*rr,i=*ii,e ;
00240  double x,y ;
00241  
00242  while (r<IF->nr) {
00243    e=min(IF->e[r],BR11) ;
00244    while (i<=e) {
00245      x=F[i]*q ;
00246      y=a[0]*x ; T[i-1] +=y ; T[i+2] -=y ;
00247      y=a[1]*x ; T[i  ] +=y ; T[i+1] -=y ;
00248      i++ ;
00249    }
00250    if (e==BR11) { *ii=i , *rr=r ; return ; }
00251    r++; 
00252    i=IF->a[r] ;
00253  }
00254 
00255 *ii=i , *rr=r ;
00256 }
00257 
00258 
00259 void OperatorMatrixInnerLoop12Even(int *ii  , int *rr   , double *F, double *T , IndexSet *IF , 
00260                                    int BR11 , double *a , double q) {
00261  int r=*rr,i=*ii,e ;
00262  double x,y ;
00263 
00264  while (r<IF->nr) {
00265    e=min(IF->e[r],BR11) ;
00266    while (i<=e) {
00267      x=F[i]*q ;
00268      y=a[0]*x ; T[i-1] +=y ; T[i+2] +=y ;
00269      y=a[1]*x ; T[i  ] +=y ; T[i+1] +=y ;
00270      i++ ;
00271    }
00272    if (e==BR11) { *ii=i , *rr=r ; return ; }
00273    r++; 
00274    i=IF->a[r] ;
00275  }
00276 
00277 *ii=i , *rr=r ;
00278 }
00279 
00280 
00281 void OperatorMatrixInnerLoop76Odd(int *ii  , int *rr   , double *F, double *T , IndexSet *IF , 
00282                                   int BR11 , double *a , double q) {
00283  int r=*rr,i=*ii,e ;
00284  double x,y ;
00285  
00286  while (r<IF->nr) {
00287    e=min(IF->e[r],BR11) ;
00288    while (i<=e) {
00289      x=F[i]*q ;
00290      y=a[0]*x ; T[i-7] +=y ; T[i+6] -=y ;
00291      y=a[1]*x ; T[i-6] +=y ; T[i+5] -=y ;
00292      y=a[2]*x ; T[i-5] +=y ; T[i+4] -=y ;
00293      y=a[3]*x ; T[i-4] +=y ; T[i+3] -=y ;
00294      y=a[4]*x ; T[i-3] +=y ; T[i+2] -=y ;
00295      y=a[5]*x ; T[i-2] +=y ; T[i+1] -=y ;
00296      y=a[6]*x ; T[i-1] +=y ; T[i  ] -=y ;
00297      i++ ;
00298    }
00299    if (e==BR11) { *ii=i , *rr=r ; return ; }
00300    r++; 
00301    i=IF->a[r] ;
00302  }
00303 
00304 *ii=i , *rr=r ;
00305 }
00306 
00307 void OperatorMatrixInnerLoop76Even(int *ii  , int *rr   , double *F, double *T , IndexSet *IF , 
00308                                   int BR11 , double *a , double q) {
00309  int r=*rr,i=*ii,e ;
00310  double x,y ;
00311  
00312  while (r<IF->nr) {
00313    e=min(IF->e[r],BR11) ;
00314    while (i<=e) {
00315      x=F[i]*q ;
00316      y=a[0]*x ; T[i-7] +=y ; T[i+6] +=y ;
00317      y=a[1]*x ; T[i-6] +=y ; T[i+5] +=y ;
00318      y=a[2]*x ; T[i-5] +=y ; T[i+4] +=y ;
00319      y=a[3]*x ; T[i-4] +=y ; T[i+3] +=y ;
00320      y=a[4]*x ; T[i-3] +=y ; T[i+2] +=y ;
00321      y=a[5]*x ; T[i-2] +=y ; T[i+1] +=y ;
00322      y=a[6]*x ; T[i-1] +=y ; T[i  ] +=y ;
00323      i++ ;
00324    }
00325    if (e==BR11) { *ii=i , *rr=r ; return ; }
00326    r++; 
00327    i=IF->a[r] ;
00328  }
00329 
00330 *ii=i , *rr=r ;
00331 }
00332 
00333 
00334 
00335 // alternative matrix-vector multiply, especially for 'completetly consistent' finite difference schemes
00336 // There is no access on interpolated values.
00337 
00338 void OperatorMatrix::MatVec2(double *T1,IndexSet *IT,int *BCT  ,  double *F,IndexSet *IF,int *BCF,
00339                              int l,int , double DX, doubleBuffer *)
00340 {
00341  if (IT->nr==0) return ;
00342 
00343  Matrix2D *CL,*CR ;
00344  int       M,N ;
00345  int       K0,K1 ;
00346  int       i,j,r,er,ar ; 
00347  double    q=pow((1<<l)/DX , power),s ;
00348 
00349  CL=CR=NULL ;
00350 
00351  IT->VecClear(T1) ;
00352 
00353  M=N= 1<<l ;
00354 
00355  if (IsWT) M-- ;
00356  if (IsWF) N-- ;
00357 
00358  K0=AL[0][0].size[0] ;
00359  K1=AL[0][0].size[1] ;
00360 
00361  if (BCF[1]!=PERIODIC) {
00362    assert(BCT[1]!=PERIODIC) ;
00363    CL =&AL [0][0] ;
00364    CR =&AR [0][0] ;
00365  } 
00366 
00367  for (r=0; r<IF->nr; r++) {
00368    ar=IF->a[r]; er=IF->e[r]; 
00369    // check size of interval
00370    assert ((er-ar+1) >= K1) ;
00371 
00372    // left boundary
00373    CL->APlusBMatVec (0.0,q, &F[ar], &T1[ar] ) ;
00374 
00375    // right boundary
00376    CR->APlusBMatVec (0.0,q, &F[er-K1+1], &T1[er-K0+1] ) ;
00377 
00378    ar += K0 ;
00379    er -= K0 ;
00380 
00381    for (i=ar; i<=er ; i++) {
00382      s=0 ;
00383      for (j=-U; j<=O; j++) s += a[U+j]*F[i-j] ;
00384      T1[i]=s*q ;
00385    }
00386  }
00387 
00388 }
00389 
00390 
00391 
00392 
00394 //
00395 //  TransformMatrix 
00396 //
00398 
00399 void TransformMatrix::MatVec (double *T1,IndexSet *IT,double *F,IndexSet *IF,int *BC,int l,int clflag, doubleBuffer *buf)
00400 {
00401  if (IT->nr==0) return ;
00402 
00403  Matrix2D *HGL,*HGR       ;
00404  int      BL0,BL1,BR0,BR1 ;
00405  int      l2,M,N,l21,l24  ;
00406  int      r,i,j,e,je      ; 
00407  double   x,*b,*T=buf->lock(); 
00408  assert(T);
00409 
00410  HGL=HGR=NULL ;
00411 
00412  // get dimensions H/GJ is a (0,..,M)x(0,..,N) matrix
00413  N=1<<l ;
00414  l2=M=1<<(l-1) ; if(IsWT) M-- ;
00415  l21=l2-1 ;
00416  l24=l2*4 ; 
00417 
00418  if (BC[1]!=PERIODIC) {i=BC[0]+1 ; j=BC[1]+1 ;}
00419                        else {i=j=0 ;}
00420 
00421  BL0=AL[i].size[0]-1 ;             // Groessen der Randbloecke 
00422  BL1=AL[i].size[1]-1 ;
00423 
00424  BR0=AR[j].size[0]-1 ; BR0=M-BR0 ;
00425  BR1=AR[j].size[1]-1 ; BR1=N-BR1 ;
00426 
00427  // dirty hack for hat functions
00428  if (BL1==-1) { BL1=0 ; BR1=N ; }
00429 
00430  // clear T
00431  if (clflag) IT->VecClear(T)   ;
00432        else  IT->VecCopy(T,T1) ;
00433 
00434  // left boundary
00435  r=0 ; 
00436  if (BC[1]!=PERIODIC) {
00437    HGL=&AL[BC[0]+1] ; 
00438    HGR=&AR[BC[1]+1] ;
00439    while (r<IF->nr) {
00440      HGL->AdaptiveAPlusBMatVec(1.0,1.0,F,T,IF->a[r],min(IF->e[r],BL1)) ;
00441      e=min(IF->e[r],BL1);
00442      for (i=IF->a[r];i<=e;i++) {
00443        x=F[i] ;
00444        for (j=max((i-O+1)/2,BL0+1);j<=min((i+U)/2,BR0-1);j++) T[j] +=a[i+U-2*j]*x ;
00445      }
00446      if(e==BL1) goto innen ; // Achtung: i ist entweder F->a[r], falls e< BL1     ODER     i==BL1+1 falls e==BL1
00447      r++ ;
00448     }
00449  } else { // pericodic BC
00450    while (r<IF->nr) {
00451      e=min(IF->e[r],BL1) ;
00452      for (i=IF->a[r];i<=e;i++) {
00453        x=F[i] ; je=(i+U)/2+l24 ; b=&a[i+U+2*l24] ;
00454        for (j=ceil2(i-O)+l24; j<=je; j++) T[j&l21] +=b[-2*j]*x ;
00455      }
00456      if(e==BL1) goto innen ;
00457      r++ ;
00458    }
00459  }
00460 
00461 //
00462 // Inneres 
00463  i=-MAXINT ; // duerfte nie durchlaufen werden, wenn r < IF->nr
00464 innen: ;
00465 
00466  if ((U==0) && (O==0) && (fabs(a[0]-1.0)<1e-14)) { 
00467    TransformMatrixInnerLoop00(&i,&r, F,T , IF , BR1-1 , a) ; 
00468    goto rechts ;
00469   }
00470 
00471  while (r<IF->nr) {
00472    e=min(IF->e[r],BR1-1) ;
00473    while (i<=e) {
00474      x=F[i] ; b=&a[i+U] ; je=(i+U)/2 ;
00475      for (j=(i-O+1)/2;j<=je;j++) T[j] +=b[-2*j]*x ;
00476      i++ ; 
00477    } 
00478    if (e==BR1-1) goto rechts ;
00479    r++; 
00480    i=IF->a[r] ;
00481  }
00482 
00483 
00484 // right boundary 
00485 
00486 rechts: ;
00487  if (BC[1]!=PERIODIC) {
00488    while (r < IF->nr) {
00489      HGR->AdaptiveAPlusBMatVec (1.0,1.0,&F[BR1],&T[BR0],max(IF->a[r]-BR1,0),min(IF->e[r],N)-BR1) ;
00490      for (i=max(i,IF->a[r]);i<=IF->e[r];i++) {
00491        x=F[i] ;
00492        for (j=max((i-O+1)/2,BL0+1);j<=min((i+U)/2,BR0-1);j++) T[j] +=a[i+U-2*j]*x ;
00493       }
00494      r++ ;
00495    }
00496  } else {  // periodic BC
00497    while (r < IF->nr) {
00498      for (i=max(i,IF->a[r]);i<=min(IF->e[r],2*l2-1);i++) {
00499        x=F[i] ; je=(i+U)/2+l24 ; b=&a[i+U+2*l24] ;
00500        for (j=ceil2(i-O)+l24; j<=je; j++) T[j&l21] +=b[-2*j]*x ;
00501       }
00502      r++ ;
00503    }
00504  }
00505 
00506  //copy: ; 
00507  IT->VecCopy(T1,T) ;
00508  buf->unlock() ;
00509 }
00510 
00511 //
00512 // Fast Inner Loops
00513 //
00514 void TransformMatrixInnerLoop00(int *ii  , int *rr   , double *F, double *T , IndexSet *IF , 
00515                                 int BR11 , double *) {
00516  int r=*rr,i=*ii,e,ia ;
00517   
00518  while (r<IF->nr) {
00519    e=min(IF->e[r],BR11) ;
00520    ia=i ;
00521    i =(i+1) & 0xfffffe  ; // round (up) to even
00522    while (i<=e) {
00523      T[i>>1] += F[i] ;
00524      i +=2 ;
00525    }
00526    if (e==BR11) { *ii=max(e+1,ia) , *rr=r ; return ; }
00527    r++; 
00528    i=IF->a[r] ;
00529  }
00530 
00531 *ii=i , *rr=r ;
00532 }
00533 
00534 
00535 
00536 // multiply by transpose matrix
00537 void TransformMatrix::MatTVec (double *T1,IndexSet *IT,double *F,IndexSet *IF,int *BC,int l,int clflag, doubleBuffer *buf)
00538 {
00539  if (IT->nr==0) return ;
00540 
00541  Matrix2D *HGL=NULL,*HGR=NULL ;
00542  int       l2,M,N,l21,l24 ;
00543  int       BL1,BR0,BR1 ;
00544  int       i,j,e,r,je ;
00545  double    x,*b, *T=buf->lock(); assert(T);
00546 
00547  // get dimensions
00548  M =1<<(l+1) ;
00549  l2=N=1<< l  ; if(IsWT) N-- ;
00550  l21=M-1; l24=M*4 ;
00551 
00552  if (BC[1]!=PERIODIC) {i=BC[0]+1; j=BC[1]+1;}
00553                        else {i=j=0;}
00554 
00555  //BL0=AL[0].size[1]-1 ;             // Groessen der Randbloecke 
00556  BL1=AL[i].size[0]-1 ;
00557  BR0=AR[j].size[1]-1 ; BR0=M-BR0 ;
00558  BR1=AR[j].size[0]-1 ; BR1=N-BR1 ;
00559 
00560  // clear T
00561  if (clflag) IT->VecClear(T)   ;
00562        else  IT->VecCopy(T,T1) ;
00563 
00564  //left 
00565  r=0 ; 
00566  if (BC[1]!=PERIODIC) {
00567    HGL=&AL[BC[0]+1] ; 
00568    HGR=&AR[BC[1]+1] ;
00569    while (r<IF->nr) {
00570      HGL->AdaptiveAPlusBMatTVec(1.0,1.0,F,T,IF->a[r],min(IF->e[r],BL1)) ;
00571      e=min(IF->e[r],BL1);
00572      for (i=max(IF->a[r],BL1+1);i<=e;i++) {
00573        x=F[i] ;
00574        for (j=2*i-U;j<=2*i+O;j++) T[j] +=a[j-2*i+U]*x ;
00575      }
00576      if(e==BL1) goto innen ; // Achtung: i ist entweder F->a[r], falls e< BL1     ODER     i==BL1+1 falls e==BL1
00577      r++ ;
00578     }
00579  } else { // periodic BC
00580    while (r<IF->nr) {
00581      e=min(IF->e[r],BL1) ;
00582      for (i=IF->a[r];i<=e;i++) {
00583        x=F[i] ; je=2*i+O+l24 ; b=&a[-2*i+U -l24] ;
00584        for (j=2*i-U+l24; j<=je; j++) T[j&l21] +=b[j]*x ; 
00585      }
00586      if(e==BL1) goto innen ;
00587      r++ ;
00588    }
00589  }
00590 
00591 
00592 //
00593 // Inneres 
00594  i=-MAXINT ; // duerfte nie durchlaufen werden, wenn r < IF->nr
00595 innen: ;
00596  if ((U==5) && (O==5) && (fabs(a[0]-a[10])<1e-14)) { 
00597    TransformMatrixTransposeInnerLoop55(&i,&r, F,T , IF , BR1-1 , a) ;
00598    goto rechts ;
00599   }
00600  if ((U==-1) && (O==1) && (fabs(a[0]-1.0)<1e-14)) { 
00601    TransformMatrixTransposeInnerLoopM11(&i,&r, F,T , IF , BR1-1 , a) ;
00602    goto rechts ;
00603   }
00604 
00605 
00606  while (r<IF->nr) {
00607    e=min(IF->e[r],BR1-1) ;
00608    while (i<=e) {
00609      x=F[i] ; b=&a[-2*i+U] ; je=2*i+O ;
00610      for (j=2*i-U;j<=je;j++) T[j] +=b[j]*x ;
00611      i++ ; 
00612    } 
00613    if (e==BR1-1) goto rechts ;
00614    r++; 
00615    i=IF->a[r] ;
00616  }
00617 
00618 // right
00619 rechts: ;
00620  if (BC[1]!=PERIODIC) {
00621    while (r < IF->nr) {
00622      HGR->AdaptiveAPlusBMatTVec (1.0,1.0,&F[BR1],&T[BR0],max(IF->a[r]-BR1,0),min(IF->e[r],N)-BR1) ;
00623      for (i=max(i,IF->a[r]);i<=min(IF->e[r],BR1-1);i++) {
00624        x=F[i] ;
00625        for (j=2*i-U;j<=2*i+O;j++) T[j] +=a[j-2*i+U]*x ;
00626       }
00627      r++ ;
00628    }
00629  } else {  // periodic BC
00630    while (r < IF->nr) {
00631      for (i=max(i,IF->a[r]);i<=min(IF->e[r],l2-1);i++) {
00632        x=F[i] ; je=2*i+O+l24 ; b=&a[-2*i+U -l24] ;
00633        for (j=2*i-U+l24; j<=je; j++) T[j&l21] +=b[j]*x ;
00634       }
00635      r++ ;
00636    }
00637  }
00638 
00639  IT->VecCopy(T1,T) ;
00640  buf->unlock() ;
00641 }
00642 
00643 //
00644 // Fast Inner Loops
00645 //
00646 void TransformMatrixTransposeInnerLoop55(int *ii  , int *rr   , double *F, double *T , IndexSet *IF , 
00647                                          int BR11 , double *a) {
00648  int r=*rr,i=*ii,e,i2 ;
00649  double x,y ;
00650  
00651  while (r<IF->nr) {
00652    e=min(IF->e[r],BR11) ;
00653    while (i<=e) {
00654      x=F[i] ;
00655      i2=2*i ;
00656      y=a[0]*x ; T[i2-5] +=y ; T[i2+5] +=y ;
00657      y=a[2]*x ; T[i2-3] +=y ; T[i2+3] +=y ;
00658      y=a[4]*x ; T[i2-1] +=y ; T[i2+1] +=y ;
00659      T[i2] +=x ; 
00660      i++ ;
00661    }
00662    if (e==BR11) { *ii=i , *rr=r ; return ; }
00663    r++; 
00664    i=IF->a[r] ;
00665  }
00666 
00667 *ii=i , *rr=r ;
00668 }
00669 
00670 void TransformMatrixTransposeInnerLoopM11(int *ii  , int *rr   , double *F, double *T , IndexSet *IF , 
00671                                           int BR11 , double *) {
00672  int r=*rr,i=*ii,e ;
00673  double *T1=T+1 ;
00674   
00675  while (r<IF->nr) {
00676    e=min(IF->e[r],BR11) ;
00677    while (i<=e) {
00678      T1[2*i] +=F[i] ;
00679      i++ ;
00680    }
00681    if (e==BR11) { *ii=i , *rr=r ; return ; }
00682    r++; 
00683    i=IF->a[r] ;
00684  }
00685 
00686 *ii=i , *rr=r ;
00687 }
00688 
00689 
00691 //
00692 // non-adaptive Matrix-Vector multiplies
00693 //
00695 
00696 void OperatorMatrix::MatVec(double *T,int *BCT  ,  double *F,int *BCF,  int J, double DX) {
00697  int i,j, nJ=1<<J ,b,e ;
00698 
00699  double *au=&a[U] , q=pow( nJ/DX , power) , s ;
00700 
00701  if (BCF[1]==PERIODIC) {
00702  
00703    assert(BCT[1]==PERIODIC) ;
00704 
00705    int mask=nJ-1 ;
00706    for (i=nJ ;i<2*nJ ;i++) {
00707      s = 0 ; 
00708      for (j=-U; j<=O; j++) s+=au[j]*F[(i-j)&mask] ;
00709      T[i-nJ]=s*q ;
00710     }
00711    T[nJ]=0.0 ;
00712 
00713  } else {
00714 
00715    int KL0,KL1,KR0,KR1 , BL0,BL1,BR0,BR1 ;
00716    KL0=AL[0][0].size[0] ; KL1=ALT[0][0].size[1] ;
00717    KR0=AR[0][0].size[0] ; KR1=ART[0][0].size[1] ;
00718 
00719    BL1=AL[0][0].size[1]-1 ; BL0=KL0+ALT[0][0].size[0]-1 ;
00720    BR1=AR[0][0].size[1]-1 ; BR0=KR0+ART[0][0].size[0]-1 ;
00721 
00722    assert((BL0+0+KR0)<=nJ) ;
00723    assert((BL1+0+KR1)<=nJ) ;
00724 
00725    KR0=nJ-KR0 ; KR1=nJ-KR1 ;
00726    BR0=nJ-BR0 ; BR1=nJ-BR1 ;
00727  
00728    Matrix2D *ALB,*ALBT,*ARB,*ARBT ;
00729    ALB =&AL [BCT[0]+1][BCF[0]+1] ;
00730    ALBT=&ALT[BCT[0]+1][BCF[0]+1] ;
00731    ARB =&AR [BCT[1]+1][BCF[1]+1] ;
00732    ARBT=&ART[BCT[1]+1][BCF[1]+1] ;
00733 
00734    // Inner scaling functions
00735  
00736    for (i=KL0; i<=KR1; i++) {
00737      b=max(i-U , KL1) ;
00738      e=min(i+O , KR1) ; 
00739      s=0 ; 
00740      for (j=b; j<=e; j++) s+=au[i-j]*F[j] ;
00741      T[i]=s*q ;
00742     }
00743 
00744    // 
00745    // Multiply for boundaries
00746 
00747     ALB->APlusBMatVec(0.0,q,F,T) ;
00748    ALBT->APlusBMatVec(1.0,q,F,&T[KL0]) ;
00749 
00750     ARB->APlusBMatVec(0.0,q,&F[BR1  ],&T[KR0+1]) ;
00751    ARBT->APlusBMatVec(1.0,q,&F[KR1+1],&T[BR0  ]) ;
00752 
00753  }
00754 
00755 }
00756 
00757 void LiftingMatrix::MatTVec(double *T1,IndexSet *IT  , double *F,IndexSet *IF, int *BC, int J , int add, doubleBuffer *buf) {
00758  int i,j,r,e,p, N=1<<J , M=N-1 , b0=BC[0] , b1=BC[1] ;
00759  
00760  // nothing to do ?
00761  if (IT->nr==0) return ;
00762  if (IF->nr==0) {
00763    if (add==0) IT->VecClear(T1) ;
00764    return ;
00765  }
00766 
00767  double *T=buf->lock(); assert(T);
00768  double s, *b, q = (add>=0) ? 1 : -1 ;
00769 
00770  // clear T
00771  if (add==0) IT->VecClear(T)   ;
00772        else  IT->VecCopy(T,T1) ;
00773  
00774  if (b1==PERIODIC) {
00775    for (r=0; r<IF->nr; r++) {
00776      e=min(IF->e[r],M) ;
00777      for (i=IF->a[r]; i<=e; i++) {
00778        s = q*F[i] ;
00779        b = &a[U-N-i] ;
00780        p = i+O+N ;
00781        for (j=i-U+N; j<=p; j++) T[j&M] +=b[j]*s ;
00782      }
00783     }
00784    IT->VecCopy(T1,T) ;
00785    buf->unlock() ;
00786    return ;
00787  }
00788 
00789  //
00790  // not periodic
00791 
00792  int BWL=QL[b0+1].size[0]-1 ,
00793    //  BL =QL[b0+1].size[1]-1 ,
00794      BVL=BWL+PL[b0+1].size[0] ,
00795      BWR=M-QR[b1+1].size[0]+1 ,
00796      BR =N-QR[b1+1].size[1]+1 ,
00797      BVR=BWR-PR[b1+1].size[0] ;
00798 
00799  int n=IF->nr ;
00800 
00801  //
00802  // Boundary Multiplication, at most the first run can touch the boundary and if it does, it covers completely
00803  // the boundary block
00804  r=0 ;
00805  i=IF->a[0] ;
00806 
00807  // left boundary
00808  if (i<=BWL) {
00809    e=min(IF->e[0] , BWL) ;
00810    QL[b0+1].AdaptiveAPlusBMatTVec(1.0 , q ,  F , T , i,e) ;
00811    if (e==IF->e[0]) { r++ , i=IF->a[r] ; }
00812                else   i=e+1 ;
00813   }
00814 
00815  // inner
00816  while (r<n) {
00817    e=min(IF->e[r],BWR-1) ;
00818    while (i<=e) {
00819      b=&a[U-i] ;
00820      if (i<=BVL) b=&PL[b0+1].a[i-BWL-1][U-i] ;
00821      if (i>=BVR) b=&PR[b1+1].a[i-BVR  ][U-i] ;
00822      s =q*F[i] ;
00823      p =i+O ;
00824      for (j=i-U; j<=p; j++) T[j] +=b[j]*s ;
00825      i++ ;
00826    }
00827    r++ ;
00828    i=IF->a[r] ;
00829  }
00830 
00831  // right boundary
00832  i=IF->a[n-1];
00833  e=min(M,IF->e[n-1]) ;
00834  if (e>=BWR) QR[b1+1].AdaptiveAPlusBMatTVec(1.0 , q ,  &F[BWR] , &T[BR] , max(i-BWR,0) , e-BWR) ;
00835  
00836  IT->VecCopy(T1,T) ;
00837  buf->unlock() ;
00838 }
00839 
00840 void LiftingMatrix::MatTVec(double *T, double *F , int *BC , int J , int add) {
00841  int i,j,e, N=1<<J , M=N-1 , b0=BC[0] , b1=BC[1] ;
00842 
00843  double s,*b,q = (add>=0) ? 1 : -1 ;
00844    
00845  if (add==0) for (i=0; i<=N; i++) T[i]=0 ;
00846 
00847  if (b1==PERIODIC) {
00848    for (i=0; i<N; i++) {
00849      s = q*F[i] ;
00850      b = &a[U-N-i] ;
00851      e = i+O+N ;
00852      for (j=i-U+N; j<=e; j++) T[j&M] +=b[j]*s ;
00853    }
00854    T[N]=0 ;
00855    return ;
00856  }
00857 
00858  int BWL=QL[b0+1].size[0]-1 ,
00859    //     BL =QL[b0+1].size[1]-1 ,
00860      BVL=BWL+PL[b0+1].size[0] ,
00861      BWR=M-QR[b1+1].size[0]+1 ,
00862      BR =N-QR[b1+1].size[1]+1 ,
00863      BVR=BWR-PR[b1+1].size[0] ;
00864 
00865  //
00866  // Rand-Multiplikation
00867  QL[b0+1].APlusBMatTVec(1.0 , q ,  F    , T) ;
00868  QR[b1+1].APlusBMatTVec(1.0 , q , &F[BWR],&T[BR]) ;
00869  
00870  // innen
00871  for (i=BWL+1; i<=BWR-1; i++) {
00872    b=&a[U] ;
00873    if (i<=BVL) b=&PL[b0+1].a[i-BWL-1][U] ;
00874    if (i>=BVR) b=&PR[b1+1].a[i-BVR  ][U] ;
00875    s =q*F[i] ;
00876    e =i+O ;
00877    for (j=i-U; j<=e; j++) T[j] +=b[j-i]*s ;
00878  }
00879 }

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