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  

PO.cc

00001 // adaptive solution of a Poisson-Problem with Dirichlet boundary conditions. 
00002 // The common solve-refine- cycle is employed to successively increase accuracy.
00003 // The threshold parameter for the adaptive refinement criterion is 1e-4. 
00004 //
00005 // For the discretization 4th order Interpolets and  4th order finite differences are used. 
00006 
00007 # include "AdaptiveData.hpp"
00008 # include "Solver.hpp"
00009 # include "UniformData.hpp"
00010 # include "Function.hpp"
00011 
00012 int debugRefine ;
00013 
00014 #define D 2 
00015 int main() {
00016  Wavelets WC("Interpolet",4) ;
00017  
00018  int i,k,BC[D][2], GBC[D][2];
00019  // boundary condition flags:
00020  // 0 means Dirichlet BC at the respective face 
00021  // 1 means Neumann   BC at the respective face 
00022  //
00023  // try to play around a little bit with the settings
00024  // at least one face must have Dirichlet b.c. to make sure the linear systems have a unique solution,
00025  // BiCG tends to diverge otherwise ....
00026  BC[0][0]=0 ; // face x=0
00027  BC[0][1]=1 ; //      x=1 
00028  BC[1][0]=1 ; //      y=0
00029  BC[1][1]=1 ; //      y=1
00030 
00031  for (i=0; i<D; i++) GBC[i][0]=GBC[i][1]=-1;
00032 
00033  // set parameters
00034  AdaptivityCriterion  R(AdaptivityCriterion::L2_THRESHOLD, 1e-4) ; // refinement criterion: |u_lt| >= 1e-4
00035  R.MaxLevel   =LMAX-1 ;                                            // and |l|_infty < JMAX-1
00036  int    LL    =10     ;                                            // uniform grid for error evaluation has mesh size 2^{-10}
00037 
00038  printf("Refinement: MaxLevel=%d  threshold=%e\n",R.MaxLevel, R.eps) ;
00039 
00040  GeneralRadialFunction<D>        FU  ;  // true solution: u(x,y)=(1e-8 + (x-3/9)^2 + (y-4/9)^2)^(1/4)
00041  GeneralRadialFunctionDX<D>      FDX ;  // dx u(x,y), required for Neumann boundary conditions
00042  GeneralRadialFunctionDY<D>      FDY ;  // dy u(x,y),      "     "     "      "         "
00043  LaplaceGeneralRadialFunction<D> LU  ;  // Laplacian,      "     "   r.h.s.
00044  
00045  double p[4]={0.5,1e-8, 3./9 , 4./9} ;
00046  FU .SetParameters(p) ;
00047  LU .SetParameters(p) ;
00048  FDX.SetParameters(p) ;
00049  FDY.SetParameters(p) ;
00050 
00051  // functions for boundary values:
00052  // evaluate FU or FDX or FDY at the faces x[i]=k
00053  SubFunction FBV[D][2] ;
00054  double v[4]={0,D,0,0} ;
00055  for (i=0; i<D; i++)
00056    for (k=0; k<2; k++) {
00057      *((Function **)v) = (BC[i][k]==0) ? (Function *)&FU : ( (i==0) ? (Function *)&FDX : (Function *)&FDY ) ;
00058      v[2]=i ;
00059      v[3]=k ; 
00060      FBV[i][k].SetParameters((double *)v) ;
00061    }
00062 
00063  // adaptive data structures
00064  AdaptiveGrid<D> G(&WC) ;
00065  G.SetPeriodicConditions(BC) ;
00066 
00067  // very coarse initial grid
00068  G.SetFull(WC.Level0+0)  ;
00069 
00070  // U : solution
00071  // UB: function which takes the boundary  values 
00072  // AC: AC(l,t) >0 if the corresponding wavelet coefficient actually fulfills the refinement criterion
00073  AdaptiveData<D> U(&G),UB(&G),RHS(&G),AC(&G),*Tmp0=G.tmp[0], *Tmp1=G.tmp[1], *Tmp2=G.tmp[2];
00074 
00075  U.SetRefine()  ; // U shall be refined
00076  AC.SetRefine() ; // the flag field too
00077 
00078  U.SetBoundaryConditions (BC ) ; // some initial values
00079  AC.SetBoundaryConditions(GBC) ;
00080  U.Set(0.0)                    ;
00081  AC.Set(0.0)                   ;
00082 
00083  // AdaptiveData for boundary values
00084  AdaptiveData<D-1> *BV[2][2] ; 
00085  for (i=0; i<D; i++)
00086    for (k=0; k<2; k++) BV[i][k]=new AdaptiveData<D-1>(G.FaceGrid[i][k]) ;
00087 
00088  // operator
00089  HelmholtzOperator  <AdaptiveData<D>,D> Laplace ; 
00090  Laplace.Tmp =G.tmp[AdaptiveGrid<D>::NUM_TMP-1] ; // auxiliary AdaptiveData required for evaluation 
00091  Laplace.Tmp2=G.tmp[AdaptiveGrid<D>::NUM_TMP-2] ; // Apply() automatically uses 4th order finite 
00092  Laplace.par[0]=0 ; // 0*U +1*dxxU +1*dyyU        // differences for 4th order Interpolets!
00093  Laplace.par[1]=1 ;
00094  Laplace.par[2]=1 ;
00095 
00096  Solver<AdaptiveData<D>,D> S ;
00097  S.eps          =1e-14 ;                             // stop if residual smaller than 1e-14 
00098  S.maxiter      =2000  ;                             // do 200 iterations at most
00099  S.Op           =&Laplace ;                          // use Laplace.Apply(.,.) for Matrix-vector multiply 
00100  S.print        =NULL ;
00101  S.prstep       =1    ;
00102  S.StopCriterion=StoppingCriterionAbsoluteResidual ; // use this residual
00103 
00104  for (i=0; i<Solver<AdaptiveData<D>,D>::NUMTMP_BICGSTAB2; i++) S.Tmp[i]=G.tmp[i] ;
00105 
00106  double   errL1 , errL2,  errLmax, AerrL1, AerrL2, AerrLmax ;
00107 
00108  int LM[2]={LL,LL},  A[2]={0,0},E[2]={1<<LM[0], 1<<LM[1]} ;
00109  UniformData<D> M(A,E,&WC), C(A,E,&WC);
00110  
00111  int cgit=10, ll[D], innerloop=0, maxused, dof,cgitmax=5 ;
00112 
00113  printf("output format for L_1 / L_2 / L_infty -errors evaluated on full grids (full) and adaptive grids (adp):\n") ;
00114  printf("                          L_1(full)    L_1(adp)   |   L_2(full)    L_2(adp)   | L_infty(full) L_infty(adp)| max level #DOF BiCG iter\n") ;
00115  
00116  // refinement loop
00117  while ( (cgit > cgitmax) && (innerloop<35) ) {
00118 
00119    // generate right hand side
00120    RHS.SetFunction(&LU) ;
00121 
00122    // generate (interpolants) of boundary values on all faces
00123    for (i=0; i<D; i++) 
00124      for (k=0; k<2; k++) BV[i][k]->SetFunction(&FBV[i][k]) ;
00125 
00126    // compute function which takes the boundary values
00127    UB.SetBoundaryValueFunction(BV,BC,true) ;
00128 
00129    // put on r.h.s.
00130    Laplace.Apply (&UB,Tmp0) ; 
00131    RHS.MMinus(Tmp0)         ;
00132 
00133    for (i=0; i<D; i++) RHS.ApplyOp(BC[i], &RHS, i, PROJECTION) ; // project to test space (with homogeneous b.c.)
00134 
00135    cgit = S.BiCGSTAB2(&U,&RHS) ; // solve
00136           S.BiCGSTAB2(&U,&RHS) ; // re-iteration
00137 
00138    for (i=0; i<D; i++) Tmp0->ApplyOp(GBC[i], (i==0) ? &U : Tmp0, i, PROJECTION) ; // transform to basisfunctions without b.c.
00139    UB.PPlus(Tmp0) ;  // UB is complete solution including the Dirichlet-boundary values
00140   
00141    // errors and output
00142    //
00143    // Adaptive Error Calculation
00144    Tmp1->SetFunction(&FU) ; // true solution
00145    Tmp1->MMinus(&UB) ;      // error
00146    AerrL1  =Tmp1->L1Norm  (Tmp2) ;
00147    AerrL2  =Tmp1->L2Norm  (Tmp2) ;
00148    AerrLmax=Tmp1->LmaxNorm(Tmp2) ;
00149       
00150    // Full Grid Error Calculation
00151    UB.ToUniform(&M,LM) ;
00152    for (i=0; i<D; i++) M.ApplyOp(GBC[i], &M, i, INVERSETRANSFORM) ;
00153 
00154    C.SetBoundaryConditions(GBC) ;
00155    C.SetFunction(&FU,false,true) ;
00156    C.MMinus(&M) ;
00157 
00158    C.Abs(&C) ;
00159    errL1  =C.Sum() / (E[0]*E[1]) ;
00160    errL2  =sqrt( C.InnerProd(&C)/(E[0]*E[1]) ) ;
00161    errLmax=C.Max() ;
00162 
00163    // info on grid
00164    G.LargestActiveLevel(ll)     ;
00165    maxused=max(ll[0],ll[1])     ;
00166    dof=G.Size() ;
00167 
00168    printf("Error(%2d,%e): %e %e | %e %e | %e %e | %2d %4d %d\n", R.MaxLevel,R.eps, 
00169            errL1,AerrL1, errL2,AerrL2, errLmax, AerrLmax, maxused, dof, cgit) ;
00170  
00171    // refinement
00172    if ((cgit> cgitmax) || (innerloop==0) ) {
00173               
00174      // compute wavelet coefficients to be used for refinement control
00175      Tmp0->Abs(&UB) ;
00176      Tmp0->Add(1.0,Tmp0, 1.0,&AC) ; //entries once marked as active will again and again be marked as active ! 
00177      
00178      // refine and save the information about the active entries
00179      G.Refine(Tmp0 , &R, &AC) ;  
00180      innerloop++ ;
00181    } 
00182  } // refinement loop
00183   
00184  UB.WriteSparse("../../Data/Test/U.adp") ;
00185  M.WriteUDF("../../Data/Test/U") ;
00186 
00187 }

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