Main Page   Data Structures   File List   Data Fields   Globals  

fas.c

Go to the documentation of this file.
00001 /* --------------------------------------------------------------------- */
00002 /* 
00003    SCCS information: %W% %G%
00004 */
00005 /* --------------------------------------------------------------------- */
00006 
00007 #include "utilf.h"
00008 #include "mymalloc.h"
00009 #include "make_bc.h"
00010 #include "fas.h"
00011 
00012 /* --------------------------------------------------------------------- */
00013 
00014 #define COARSEST     1
00015 #define COARSERELAX  4
00016 
00017 static real2D  *itau, *irhs, *irho, *ip, *ia, *ib, *iei, *itemp, *icc;
00018 
00019 static void abfromab(real2D a, real2D b, real2D ei, real2D a2, real2D c2, 
00020                      int n1, int n2);
00021 
00022 static void rstrct(real2D uc, real2D uf, int ncx, int ncy);
00023 
00024 static void interp(real2D uf, real2D uc, int nfx, int nfy);
00025 
00026 static void slvsml(real2D u, real2D rhs, 
00027                    real2D a, real2D b, real2D ei, 
00028                    int nfx, int nfy);
00029 
00030 void lop(real2D out, real2D u, real2D a, real2D b, 
00031          int n1, int n2);
00032 
00033 /* --------------------------------------------------------------------- */
00034 
00035 int computeng(int n1, int n2)
00036 {
00037   int nmin, n, nn, j;
00038 
00039   nmin = min(n1, n2);
00040   
00041   j = nmin - 2;  n = 1;
00042   while (j > 2) 
00043   {  j /= 2;   n++;  }
00044   
00045   nn = 1;  
00046   for (j = 1; j <= n; j++) 
00047     nn *= 2;       
00048   if((nn + 2) != nmin)
00049      return NGERROR;
00050 
00051   if ((n1 - 2) % (nmin - 2) != 0)
00052      return NXERROR;
00053   if ((n2 - 2) % (nmin - 2) != 0)
00054      return NYERROR;
00055   
00056   return n;
00057 }
00058 
00059 /* --------------------------------------------------------------------- */
00060 
00061 int initpressure(int n1, int n2, int ng)
00062 {
00063   int j;
00064   
00065   irhs = (real2D *) malloc((ng + 1) * sizeof(real2D));
00066   irho = (real2D *) malloc((ng + 1) * sizeof(real2D));
00067   itau = (real2D *) malloc((ng + 1) * sizeof(real2D));
00068   ip = (real2D *) malloc((ng + 1) * sizeof(real2D));
00069   ia = (real2D *) malloc((ng + 1) * sizeof(real2D));
00070   ib = (real2D *) malloc((ng + 1) * sizeof(real2D));
00071   iei = (real2D *) malloc((ng + 1) * sizeof(real2D));
00072   itemp = (real2D *) malloc((ng + 1) * sizeof(real2D));
00073   icc = (real2D *) malloc((ng + 1) * sizeof(real2D));
00074   
00075   if (icc EQUALS NULL)
00076       return MEMERROR;
00077   
00078   irhs[ng] = (real2D)mymalloc(sizeof(real), n1, n2);
00079   itau[ng] = (real2D)mymalloc(sizeof(real), n1, n2); 
00080   itemp[ng] = (real2D)mymalloc(sizeof(real), n1, n2);
00081 
00082   n1 = n1 / 2 + 1;
00083   n2 = n2 / 2 + 1;
00084 
00085   for (j = ng - 1; j >= 1; j--)
00086     {
00087       irhs[j] = (real2D)mymalloc(sizeof(real), n1, n2); 
00088       irho[j] = (real2D)mymalloc(sizeof(real), n1, n2); 
00089       itau[j] = (real2D)mymalloc(sizeof(real), n1, n2); 
00090       ip[j] = (real2D)mymalloc(sizeof(real), n1, n2); 
00091       ia[j] = (real2D)mymalloc(sizeof(real), n1, n2);
00092       ib[j] = (real2D)mymalloc(sizeof(real), n1, n2); 
00093       iei[j] = (real2D)mymalloc(sizeof(real), n1, n2); 
00094       icc[j] = (real2D)mymalloc(sizeof(real), n1, n2);
00095       itemp[j] = (real2D)mymalloc(sizeof(real), n1, n2);
00096 
00097       if (itemp[j] EQUALS NULL)
00098         return MEMERROR;
00099 
00100       n1 = n1 / 2 + 1;
00101       n2 = n2 / 2 + 1;
00102     }
00103     
00104   return 0;
00105 } /* end initpressure() */
00106 
00107 /* --------------------------------------------------------------------- */
00108 
00109 void mginit(real2D u, real2D p, real2D a, real2D b, real2D ei, real2D cc,
00110             int n1, int n2, int ng) 
00111 {
00112   int ngrid, nn1, nn2;
00113   
00114   ip[ng] = p;
00115   irho[ng] = u;
00116   ia[ng] = a;
00117   ib[ng] = b;
00118   iei[ng] = ei;
00119   icc[ng] = cc;
00120 
00121   nn1 = n1 / 2 + 1;
00122   nn2 = n2 / 2 + 1;
00123   ngrid = ng - 1;
00124   
00125   bc_scalar(u, n1, n2, NULGRAD);
00126 
00127   rstrct(irho[ngrid], u, nn1, nn2);
00128   rstrct(icc[ngrid], p, nn1, nn2);  
00129   abfromab(ia[ngrid], ib[ngrid], iei[ngrid],
00130            ia[ngrid+1], ib[ngrid+1], nn1, nn2);
00131   while ((nn1 > 4) && (nn2 > 4))
00132     {
00133       nn1 = nn1 / 2 + 1;
00134       nn2 = nn2 / 2 + 1;
00135       ngrid = ngrid - 1;
00136       rstrct(irho[ngrid], irho[ngrid+1], nn1, nn2);
00137       rstrct(icc[ngrid], icc[ngrid+1], nn1, nn2);
00138       abfromab(ia[ngrid], ib[ngrid], iei[ngrid], ia[ngrid+1], ib[ngrid+1],
00139                nn1, nn2);
00140     }
00141 }
00142 
00143 void mgfas(real2D u, real2D p, real2D a, real2D b, real2D ei, 
00144            int n1, int n2, int ng, int npre, int npost, int ncycle)
00145 {
00146   int i, j, jj, jcycle, jpre, jpost, ngrid, nfx, nfy, nn1, nn2;
00147 
00148   ip[ng] = p;
00149   irho[ng] = u;
00150   ia[ng] = a;
00151   ib[ng] = b;
00152   iei[ng] = ei;  
00153   icc[ng] = cc;
00154 
00155   nn1 = n1 / 2 + 1;
00156   nn2 = n2 / 2 + 1;
00157   ngrid = ng - 1;
00158   
00159   bc_scalar(u, n1, n2, NULGRAD);
00160 
00161   rstrct(irho[ngrid], u, nn1, nn2);
00162   rstrct(icc[ngrid], cc, nn1, nn2);
00163   abfromab(ia[ngrid], ib[ngrid], iei[ngrid],
00164            ia[ngrid+1], ib[ngrid+1], nn1, nn2);
00165   while ((nn1 > 4) && (nn2 > 4))
00166     {
00167       nn1 = nn1 / 2 + 1;
00168       nn2 = nn2 / 2 + 1;
00169       ngrid = ngrid - 1;      
00170       rstrct(irho[ngrid], irho[ngrid+1], nn1, nn2);
00171       rstrct(icc[ngrid], icc[ngrid+1], nn1, nn2);
00172       abfromab(ia[ngrid], ib[ngrid], iei[ngrid], ia[ngrid+1], ib[ngrid+1],
00173                nn1, nn2);
00174     }
00175 
00176   ngrid = ng;
00177   for (j = 2; j <= ngrid; j++)
00178     {
00179       nn1 = 2 * nn1 - 2;
00180       nn2 = 2 * nn2 - 2;
00181       interp(ip[j], ip[j-1], nn1, nn2);
00182       copy(irhs[j], irho[j], nn1, nn2);
00183       for (jcycle = 1; jcycle <= ncycle; jcycle++)
00184         {
00185           nfx = nn1;
00186           nfy = nn2;
00187           for (jj = j; jj >= 2; jj--)
00188             {
00189               for (jpre = 1; jpre <= npre; jpre++)
00190                 {
00191                   relax(ip[jj], irhs[jj], ia[jj], ib[jj], iei[jj], icc[jj],
00192                         nfx, nfy);
00193                   bc_scalar(ip[jj], nfx, nfy, NULGRAD);
00194                 }
00195               lop(itemp[jj], ip[jj], ia[jj], ib[jj], icc[jj], nfx, nfy);              
00196               bc_scalar(itemp[jj], nfx, nfy, NULGRAD);
00197               nfx = nfx / 2 + 1;
00198               nfy = nfy / 2 + 1;
00199               rstrct(itemp[jj-1], itemp[jj], nfx, nfy);
00200               rstrct(ip[jj-1], ip[jj], nfx, nfy);
00201               lop(itau[jj-1], ip[jj-1], ia[jj-1], ib[jj-1], icc[jj-1], nfx, nfy);
00202               bc_scalar(itau[jj-1], nfx, nfy, NULGRAD);
00203               matsub(itau[jj-1], itemp[jj-1], itau[jj-1], nfx, nfy);
00204               rstrct(irhs[jj-1], irhs[jj], nfx, nfy);
00205               matadd(irhs[jj-1], itau[jj-1], irhs[jj-1], nfx, nfy);
00206             }
00207           
00208           slvsml(ip[1], irhs[1],
00209                  ia[1], ib[1], iei[1], icc[1], nfx, nfy);
00210           
00211           for (jj = 2; jj <= j; jj++)
00212             {
00213               rstrct(itemp[jj-1], ip[jj], nfx, nfy);
00214               matsub(ip[jj-1], itemp[jj-1], itemp[jj-1], nfx, nfy);
00215               nfx = 2 * nfx - 2;
00216               nfy = 2 * nfy - 2;
00217               interp(itau[jj], itemp[jj-1], nfx, nfy);
00218               matadd(ip[jj], itau[jj], ip[jj], nfx, nfy);
00219               for (jpost = 1; jpost <= npost; jpost++)
00220                 {
00221                   relax(ip[jj], irhs[jj], ia[jj], ib[jj], iei[jj], icc[jj],
00222                         nfx, nfy);
00223                   bc_scalar(ip[jj], nfx, nfy, NULGRAD);
00224                 }
00225             }  
00226         }
00227     }
00228 }
00229 #if 0
00230 /* --------------------------------------------------------------------- */
00231 
00232 void mgvcycle(int n, int nx, int ny, int npre, int npost)
00233 {
00234   int count;
00235   int ncx = nx / 2 + 1, ncy = ny / 2 + 1;
00236 
00237   /* solve exactly on the coarsest grid */
00238   if (n EQUALS COARSEST)
00239     {
00240       slvsml(ip[COARSEST], irhs[COARSEST], 
00241              ia[COARSEST], ib[COARSEST], iei[COARSEST], icc[COARSEST},
00242              nx, ny);
00243       return;
00244     }
00245   
00246   /* do prerelaxation */
00247   for (count = 0; count < npre; count++)
00248     {
00249       relax(ip[n], irhs[n], ia[n], ib[n], iei[n], icc[n], nx, ny);
00250       bc_scalar(ip[n], nx, ny, NULGRAD);
00251     }
00252 
00253   /* compute tau = LH(Rph) - RLh(ph) */
00254   lop(itemp[n], ip[n], ia[n], ib[n], icc[n], nx, ny);
00255   bc_scalar(itemp[n], nx, ny, NULGRAD);
00256   rstrct(itemp[n-1], itemp[n], ncx, ncy);
00257   rstrct(ip[n-1], ip[n], ncx, ncy);
00258   lop(itau[n-1], ip[n-1], ia[n-1], ib[n-1], icc[n-1], ncx, ncy);
00259   bc_scalar(itau[n-1], ncx, ncy, NULGRAD);
00260   matsub(itau[n-1], itemp[n-1], itau[n-1], ncx, ncy);
00261   
00262   /* compute r.h.s. */
00263   rstrct(irhs[n-1], irhs[n], ncx, ncy);
00264   matadd(irhs[n-1], itau[n-1], irhs[n-1], ncx, ncy);
00265 
00266   /* solve on the coarser grid */
00267   mgvcycle(n - 1, ncx, ncy, npre, npost);
00268 
00269   /* compute tau = P(pH-Rph) */
00270   rstrct(itemp[n-1], ip[n], ncx, ncy);
00271   matsub(ip[n-1], itemp[n-1], itemp[n-1], ncx, ncy);
00272   printf("--------------------itemp[%d]--------------------\n", n-1);
00273   matprint(itemp[n-1], ncx, ncy);
00274   interp(itau[n], itemp[n-1], nx, ny);
00275   printf("--------------------itau[%d]------------------\n", n);
00276   matprint(itau[n], nx, ny);
00277 
00278   /* correct on the fine grid */
00279   printf("--------------------ip[%d]--------------------\n", n);
00280   matprint(ip[n], nx, ny);
00281   matadd(ip[n], itau[n], ip[n], nx, ny);
00282 
00283   /* do post relaxation */
00284   for (count = 0; count < npost; count++)
00285     {
00286       relax(ip[n], irhs[n], ia[n], ib[n], iei[n], icc[n], nx, ny);
00287       bc_scalar(ip[n], nx, ny, NULGRAD);
00288     }
00289 }
00290 #endif
00291 /* --------------------------------------------------------------------- */
00292 
00293 static void abfromab(real2D a, real2D b, real2D ei, real2D a2, real2D c2, 
00294                      int n1, int n2)
00295 {
00296   int i, j;
00297   
00298   for (i = 1; i <= n1 - 1; i++)
00299     for (j = 2; j <= n2 - 1; j++)
00300       a[i][j] = 0.5 * (a2[2*i-1][2*j-2] + a2[2*i-1][2*j-1]);
00301   for (i = 2; i <= n1 - 1; i++)
00302     for (j = 1; j <= n2 - 1; j++)
00303       b[i][j] = 0.5 * (c2[2*i-2][2*j-1] + c2[2*i-1][2*j-1]);
00304   for (i = 2; i <= n1 - 1; i++)
00305     for (j = 2; j <= n2 - 1; j++)
00306       ei[i][j] = 1.0 / (a[i-1][j] + a[i][j] + b[i][j-1] + b[i][j]);
00307 }
00308 
00309 /* --------------------------------------------------------------------- */
00310 
00311 static void rstrct(real2D uc, real2D uf, int ncx, int ncy)
00312 {
00313   int ic, iff, jc, jf;
00314   
00315   for (jc = 2; jc <= ncx - 1; jc++)
00316     {
00317       jf = 2 * jc - 2;
00318       for (ic = 2; ic <= ncy - 1; ic++)
00319         {
00320           iff = 2 * ic - 2;
00321           uc[jc][ic] = 0.5 * uf[jf][iff] + 
00322             0.125 * (uf[jf][iff+1] + uf[jf][iff-1] + 
00323                      uf[jf+1][iff] + uf[jf-1][iff]);
00324         }
00325     }
00326   bc_scalar(uc, ncx, ncy, NULGRAD);
00327 }
00328 
00329 /* --------------------------------------------------------------------- */
00330 #if 0
00331 static void interp(real2D uf, real2D uc, int nfx, int nfy)
00332 {
00333   int ic, iif, jc, jf, ncx = nfx / 2 + 1, ncy = nfy / 2 + 1;
00334 
00335   for (jc = 1, jf = 1; jc <= ncy; jc++, jf += 2)
00336     for (ic = 1; ic < ncx; ic++)
00337       uf[2*ic-1][jf] = uc[ic][jc];
00338 
00339   for (jf = 1; jf <= nfy; jf += 2)
00340     for (iif = 2; iif < nfx; iif += 2)
00341       uf[iif][jf] = 0.5 * (uf[iif+1][jf] + uf[iif-1][jf]);
00342                            
00343   for (jf = 2; jf < nfy; jf += 2)
00344     for (iif = 1; iif <= nfx; iif++)
00345       uf[iif][jf] = 0.5 * (uf[iif][jf+1] + uf[iif][jf-1]);
00346 
00347   bc_scalar(uf, nfx, nfy, NULGRAD);
00348 }
00349 #endif
00350 
00351 static void interp(real2D uf, real2D uc, int nfx, int nfy)
00352 {
00353   int ic, iff, jc, jf, ncx, ncy;
00354   
00355   ncx = nfx / 2 + 1;
00356   ncy = nfy / 2 + 1;
00357   for (ic = 2; ic <= ncx - 1; ic++)
00358     {
00359       iff = 2 * ic - 2;
00360       for (jc = 2; jc <= ncy - 1; jc++)
00361         {
00362           jf = 2 * jc - 2;
00363           uf[iff][jf] = 
00364           uf[iff][jf+1] = 
00365           uf[iff+1][jf] = 
00366           uf[iff+1][jf+1] = uc[ic][jc];
00367         }
00368     }
00369   
00370   bc_scalar(uf, nfx, nfy, NULGRAD);
00371 }
00372 
00373 #if 0
00374 static void interp(real2D uf, real2D uc, int nfx, int nfy)
00375 {
00376   int ic, iff, jc, jf, ncx, ncy;
00377   
00378   ncx = nfx / 2 + 1;
00379   ncy = nfy / 2 + 1;
00380 
00381   for (ic = 2; ic <= ncx - 1; ic++)
00382     {
00383       iff = 2 * ic - 2;
00384       for (jc = 2; jc <= ncy - 1; jc++)
00385         {
00386           jf = 2 * jc - 2;
00387           uf[iff][jf] = uc[ic][jc];
00388         }
00389     }
00390   
00391   for (jf = 1; jf <= nfy; jf += 2)
00392     for (iff = 2; iff < nfx; iff += 2)
00393       uf[iff][jf] = 0.5 * (uf[iff+1][jf] + uf[iff-1][jf]);
00394   for (jf = 2; jf < nfy; jf += 2)
00395     for (iff = 1; iff <= nfx; iff++)
00396       uf[iff][jf] = 0.5 * (uf[iff][jf+1] + uf[iff][jf-1]);
00397 
00398   bc_scalar(uf, nfx, nfy, NULGRAD);
00399 }
00400 #endif
00401 
00402 /* --------------------------------------------------------------------- */
00403 
00404 static void slvsml(real2D u, real2D rhs, real2D a, real2D b, real2D ei, 
00405                    int nfx, int nfy)
00406 {
00407   int count;
00408   
00409   for (count = 1; count <= COARSERELAX; count++)
00410     {
00411       relax(u, rhs, a, b, ei, nfx, nfy);
00412       bc_scalar(u, nfx, nfy, NULGRAD);
00413     }
00414 }
00415 
00416 /* --------------------------------------------------------------------- */
00417 
00418 void relax(real2D u, real2D rhs, 
00419            real2D a, real2D b, real2D ei, real2D cc,
00420            int n1, int n2)
00421 {
00422   real h2, h, res;
00423   int i, j, isw, jsw;
00424 
00425   h = 1.0 / (n2 - 2);
00426   h2 = h * h;
00427   for (jsw = 1; jsw <= 2; jsw++)
00428     {
00429       isw = jsw;
00430       for (i = 2; i <= n1 - 1; i++, isw = 3 - isw)
00431         for (j = isw + 1; j <= n2 - 1; j += 2)
00432           if (cc[i][j] == 1.0)
00433             u[i][j] = (a[i][j] * u[i+1][j] +
00434                        a[i-1][j] * u[i-1][j] +
00435                        b[i][j] * u[i][j+1] +
00436                        b[i][j-1] * u[i][j-1]
00437                        - h2 * rhs[i][j]) 
00438               * ei[i][j];
00439     }
00440 }
00441 
00442 
00443 /* --------------------------------------------------------------------- */
00444 
00445 void lop(real2D out, real2D u, real2D a, real2D b, real2D cc,
00446          int n1, int n2)
00447 {
00448   int i, j;
00449   real hi2;
00450 
00451   hi2 = (real) (n2 - 2) * (n2 - 2);
00452   for (i = 2; i <= n1 - 1; i++)
00453     for (j = 2; j <= n2 - 1; j++)
00454       if (cc[i][j] == 1.0)
00455         out[i][j] = hi2 * (a[i][j] * (u[i+1][j] - u[i][j]) +
00456                            a[i-1][j] * (u[i-1][j] - u[i][j]) +
00457                            b[i][j] * (u[i][j+1] - u[i][j]) +
00458                            b[i][j-1] * (u[i][j-1] - u[i][j]));
00459 }
00460 
00461 
00462 
00463 
00464 
00465 
00466 
00467 
00468 

Generated on Wed Feb 19 22:26:49 2003 for Markers by doxygen1.2.18